So I have a technical misunderstanding of react function component re-renders or some sort, when they happen exactly. In the provided basic app, whenever I click on the theme icon on the far left of the navbar(Header.js component), a click event handler changes the state, provided by a custom hook, which is specified in the useTheme.js file. The state updates successfully, Header component re-renders, updates the theme accordingly. However, this state change is not reflected in the Box.js file, where the label of the boxes should be "This a box dark" and vice versa. What am I missing?
Thanks for your response!
https://codesandbox.io/p/sandbox/patient-water-cn35lh?file=%2Fsrc%2Fcomponents%2Fhooks%2FuseTheme.js
Regards
Tried to add a useEffect hook to the affected component to monitor state changes, but they are not reflected.
2
Answers
TL;DR: the state has to be shared over all your components. Use Context to provide the state over a subtree of components.
With every initialization of useState a new state is generated. It dose not mater if its called within a component or in your case a custom hook. Every of your components has its own custom theme-state and they share nothing.
React has context to provide a state to child-components without passing theme through via props and without the need of re rendering all child-components.
A very short example:
ThemeContext.jsx
A Example that fits more to your useTheme Hook
ThemeContext.jsx
Integrate the second Example within your app/example
App.jsx
Box.jsx
State is not shared between hook instances. Everywhere you call a hook it will create a new state. So you can have
useTheme.isDarkTheme === true
in one place anduseTheme.isDarkTheme === false
in another.If you want to achieve this with the given structure, you can use
useContext
. In that case all you need to do is updateuseTheme
and wrap your app inThemeWrapper
.Now every component that is a child to
ThemeWrapper
will receive the current values as defined inside ofThemeWrapper
when callinguseTheme
.An alternative approach would be to have one instance of your current
useTheme
hook and pass the values as properties to all components that need it.