Context store is not updated after rerender #950
-
I've created this simple sample app: import React from "react";
import {
createContextStore,
createStore,
StoreProvider,
useStoreState,
useStoreActions,
action,
} from "easy-peasy";
const myStore = createStore({
toggle: true,
doToggle: action((state) => {
state.toggle = !state.toggle;
}),
});
const ContextEnable = createContextStore((runtimeModel) => {
if (runtimeModel === undefined) {
throw new Error("Error!");
}
return { enable: runtimeModel.enable };
});
const Updater = () => {
const toggle = useStoreActions((actions) => actions.doToggle);
return <button onClick={toggle}>Update</button>;
};
const Button = () => {
const enable = ContextEnable.useStoreState((state) => state.enable);
console.log("BUTTON", enable);
return <button>Button</button>;
};
const Buttons = () => {
const toggle = useStoreState((state) => state.toggle);
console.log("BUTTONS", toggle);
return (
<ContextEnable.Provider runtimeModel={{ enable: toggle }}>
<Button />
<Button />
</ContextEnable.Provider>
);
};
const App = () => {
return (
<StoreProvider store={myStore}>
<Updater />
<hr />
<Buttons />
</StoreProvider>
);
};
export default App; If you open Console and keep clicking the "Update" button, you will see 2 log entries:
I would expect, when main store is updated and I found this question on SO for plain React (w/o easy-peasy), but I don't really get it and it seems way overcomplicated. So I was wondering:
Thanks in advance |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
I just recreated a Redux version, and this one seems to be working as expected 😕 import React, { createContext, useContext } from "react";
import { Provider, useSelector, useDispatch } from "react-redux";
import { configureStore, createSlice } from "@reduxjs/toolkit";
const toggleSlice = createSlice({
name: "toggler",
initialState: {
value: false,
},
reducers: {
doToggle: (state) => {
state.value = !state.value;
},
},
});
const myStore = configureStore({
reducer: {
toggler: toggleSlice.reducer,
},
});
const ContextEnable = createContext(false);
const Updater = () => {
const dispatch = useDispatch();
return (
<button onClick={() => dispatch(toggleSlice.actions.doToggle())}>
Update
</button>
);
};
const Button = () => {
const enable = useContext(ContextEnable);
console.log("BUTTON", enable);
return <button>Button</button>;
};
const Buttons = () => {
const toggle = useSelector((state) => state.toggler.value);
console.log("BUTTONS", toggle);
return (
<ContextEnable.Provider value={toggle}>
<Button />
<Button />
</ContextEnable.Provider>
);
};
const App = () => {
return (
<Provider store={myStore}>
<Updater />
<hr />
<Buttons />
</Provider>
);
};
export default App; |
Beta Was this translation helpful? Give feedback.
-
As stated in #951, the context store model is only initialized once - so it will only receive the initial I'll preface that I don't understand the requirement for nesting a root store with context stores, sharing states like this. Some solutions to get the updated state: |
Beta Was this translation helpful? Give feedback.
-
OMG... It's as simple as adding a This works as expected const Buttons = () => {
const toggle = useStoreState((state) => state.toggle);
console.log("BUTTONS", toggle);
return (
<ContextEnable.Provider key={toggle} runtimeModel={{ enable: toggle }}>
<Button />
<Button />
</ContextEnable.Provider>
);
}; Thanks again for pointing to the right direction 🙏 |
Beta Was this translation helpful? Give feedback.
OMG... It's as simple as adding a
key
prop to the component, which holds the context provider. Prop should be updated depending on the changed main state...This works as expected
Thanks again for pointing to the right direction 🙏