I’m stating to learn react and redux and I cannot figure out why my react component does not re-render after redux store state change.
Here is my code:
const initialState = { value: 'Loading...' }
function onSetName(state = initialState, action) {
if (action.type === 'doc/docnamechanged') {
return {
...state,
value: action.payload
}
}
return state
}
export const setName = text => {
return {
type: 'doc/docnamechanged',
payload: text
}
}
export const store = configureStore({ reducer: onSetName })
store.subscribe(() => Layout(), App());
export default function App() {
return (
<Routes>
<Route element={<Layout />}>
<Route path="/1" element={<PublicPage />} />
</Route>
</Routes>
)
}
thats my dispatch
if (store.getState().value != "AD") {
store.dispatch(setName("AD"));
}
function Layout() {
console.log(store.getState().value);
const name = store.getState().value;
return (
<div className="App">
<div className="header">
<img className="logo" src="images/logotype.png" alt="logo" />
<div className="UpperTitle">
{name}
</div>
</div>
</div>
)
}
So I can see in console that store.getState().value
does change, but in rendered <div className="UpperTitle">
{name}
does not change. As you can see I tried to subscribe my App() function as well, but that did not help at all. Appreciate any help.
I manage to make it somehow work if I subscibe render() in index.js, but that seemed wrong and cause a warning message
react-dom.development.js:86 Warning: Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.
2
Answers
Calling
store.getState
in a component doesn’t subscribe it to any changes, it simply gets the state once and that’s it. Something else would need to occur to trigger theLayout
component to rerender sostore.getState
would be called again.This isn’t how we subscribe to the store in React components though. You can use the
connect
Higher Order Component, or the more modernuseSelector
hook.You will need to ensure the Redux store is being provided to the React app.
Since it appears you are actually already using Redux-Toolkit, you should really use the current Redux patterns.
for rerender an component you need call a hook or change a state inside it!
also
Layout
is not apure function
, and you can’t call it insubscibe
,so remove this line from your code :
for rerender on store’s state change you need to change component’s state in
subscibe
:first we create a state like below in
Layout
Component :then I add a
useEffect
hook toLayout
and usesubscribe
method inside it :When the
redux state
value changes, thesubscribe
will called, after that the name state changes inLayout
and component will be rerender.you can see demo of my answer