I'm working on a large app where we're slowly integrating Redux piecemeal, essentially converting small components into "embedded Redux apps" that are the top-level of the Redux app, but not the top-level of the React app. This has worked for the most part, but we ran into this issue:
var ReduxRoot = props => (
<Provider store={props}>
<ReactReduxConnectedComponent/>
</Provider>
)
It works fine, but any time the parent component re-renders, a <Provider> does not support changingstoreon the fly error pops up in the console.
This is fixed by adding a shouldComponentUpdate, and returning false if this.props and nextProps are equal. But that prevents us from taking advantage of the stateless component pipeline.
I know it's not the idealized use of Redux to embed it within a React hierarchy instead of at the top level, so I'm not sure if this issue is considered worth addressing. But maybe it is.
I know it's not the idealized use of Redux to embed it within a React hierarchy instead of at the top level, so I'm not sure if this issue is considered worth addressing. But maybe it is.
It's totally fine, we should support this.
It works fine, but any time the parent component re-renders, a
does not support changingstoreon the fly error pops up in the console.
Please see the relevant check. It's comparing identities. This means that the store prop is different on every render. This is problematic. (You're effectively recreating store and destroying its state鈥攚hy?)
This is also a bit weird:
var ReduxRoot = props => (
<Provider store={props}>
<ReactReduxConnectedComponent/>
</Provider>
)
Shouldn't that be more like
var ReduxRoot = props => (
<Provider store={props.store}>
<ReactReduxConnectedComponent/>
</Provider>
)
?
This is also a bit weird:
Aha, that was the problem. Since the initial state of the store was the only data I needed to pass to ReduxRoot, it was basically:
<ReduxRoot {...initialStore}/>
So that meant props, even though it always had the same contents, was actually a new object being passed to <Provider>.
I fixed the problem by using your correction, except with destructuring
var ReduxRoot = ({store}) => {
for an ever-so-satisfying elimination of six characters.
I guess one way to avoid this error is if <Provider> could check to see if the store it's being passed is actually identical to its previous store, but that might add some unnecessary overhead.
Glad you found the problem! Yeah, we only rely on object identity there, something more complicated seems unwarranted.
Sorry for being a bit off topic but I'm looking for a code example that demonstrates switching between different stores in react-native. This thread seems to touch the subject.
Specifically, I want to switch between users (log in/out) where each user has its own store.
Could you point me to any articles/tutorials available online.
Thanks a lot!
Sorry too for being off topic but I'm having the same issue as @beebase. I want to change between stores in a login/logout logic in react-native, and I'm not sure how can that be done. Have you found a solution @beebase ? Thanks!
You can't change the store passed to <Provider>, but you could render a new <Provider>. Give it a key and change it when you change the store.
interesting...
never encountered a case where I need to create 2 stores and switch between them..
can't we put the switch inside store, and read different part from store state? nevertheless, I believe you have your own ground to have 2 stores
Throwing in an answer for those who searched for the Error message in the title: Don't call createStore in the provider attribute!
Don't do this:
```js
ReactDOM.render(
,
document.getElementById('root')
);
The correct way is this:
```js
var store = createStore(reducers);
ReactDOM.render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root')
);
I had the same problem as given in the title but after the advise of @totymedli, i solved my problem. I am using react-native my approach for the solution was as advised;
const store = createStore(reducers);
export default class App extends React.Component {
render() {
return (
<Provider store={store}>
<View style={{ flex: 1 }}>
<Header title="Tech Stack" />
<LibraryList />
</View>
</Provider>
);
}
}
Here is my solution:
// index.tsx
import createStore from './redux/createStore'
const store = createStore({})
const renderApp = () => {
ReactDOM.render(
<MuiThemeProvider theme={theme}>
<Provider store={store}>
<Router>
<App />
</Router>
</Provider>
</MuiThemeProvider>,
document.getElementById('root'),
)
}
renderApp()
if (module.hot) {
// only need replace entry point
module.hot.accept('./App', () => {
renderApp()
})
}
The one important thing is that should not replace the file which create the redux store. In my above example is the index.tsx.
Most helpful comment
Throwing in an answer for those who searched for the Error message in the title: Don't call
createStorein the provider attribute!Don't do this:
```js
ReactDOM.render(
,
document.getElementById('root')
);