Since the autosuggest uses its own redux store, the following use case is not possible:
renderContactSuggestion(item) {
return (
<span className={'suggestion-content'}>
{item.firstName} {item.lastName} (<I18n message={"contactType."+item.type}/>)
</span>
)
}
The I18n Component uses a redux store, where the global translation messages are stored. But when the renderer is called, there is only the store from autosuggest.
@kromit Sorry, I don't quite understand. Could you please create a Codepen that demonstrates the issue?
This is not that complicated. I18n is a connected redux component and looks like this
class I18n extends Component {
render() {
..../* translate the param using this.props.messages*/
}
}
export default connect((state)=>{
return {messages:state.app.i18n.messages}
})(I18n);
The state.app is undefined during connect if used for suggestion rendering. This happens because the state is coming from store defined in AutosuggestContainer.js. This store effectively replaces the main application store (that was defined outside of the autosuggest component) so I18n works only outside of the autosuggest but not inside of it.
I've fixed this for me by using context inside of I18n instead of redux state.
@kromit Do you have a suggestion how to improve Autosuggest for this use case?
I have no idea. I've looked into redux docs, but I've found nothing useful to fix this problem. We could evtl talk to @gaeron about this since I am not sure if this is working as intended.
@kromit Here are my initial thoughts:
Provider in react-redux always provides the context on store. Looks like react-redux doesn't have an API that allows you to have the context on something else. It would be great if you could do something like:
// AutosuggestContainer.js
import { createProvider } from 'react-redux';
const Provider = createProvider({ contextName: 'autosuggestStore' });
...
Then, we could do:
// Autosuggest.js
import { connect } from 'react-redux';
import { mapContextWith } from 'react-context-utils';
...
export default mapContextWith(context => ({ store: context.autosuggestStore }))(connect(...)(Autosuggest));
@gaearon Would be keen to hear your thoughts on how to address this issue.
@kromit Is I18n available on npm, or is it your custom component?
Don't use Provider in a library, and pass store as a prop to the connected component instead. Connect detects store in props as a fallback.
Thanks @gaearon, much simpler!
This is fixed in 3.7.3 now.
@moroshko I am not sure if the current solution will work for multiple autosuggest inputs when they are using the same store. I've not tested this, but should not every autosuggest input use a dedicated state path like based on its id or something?
The store is created in the constructor for every instance so this shouldn鈥檛 be an issue. It鈥檚 an implementation detail.
I think @kromit is right. If we pass the store to the component as a prop then every component uses the same store so the reducer needs to maintain state for every instance of the component.
Just a note that redux and react-redux dependencies were removed in v8.0.0.
Most helpful comment
Don't use Provider in a library, and pass store as a prop to the connected component instead. Connect detects store in props as a fallback.