Hi everyone I'm new to React. I was trying to create a global state using the context api. I encountered something unexpected. What I've learned is that when a context is created, it has a provider that will wrap around those components that need the data and when the value changes, the provider will rerender all the wrapped components, right?
Take a look at this:
// AuthContext.js
export const AuthContext = createContext(null);
const AuthProvider = ({ children }) => {
const [user, setUser] = useState({
name: null,
});
return (
<AuthContext.Provider value={{ user, setUser }}>
{children}
</AuthContext.Provider>
);
};
// index.js
<AuthProvider>
<App />
</AuthProvider>
// App.js
function App() {
console.log("[App] ran");
return (
<>
<Dashboard />
<Login />
</>
);
}
// Dashboard.js
function Dashboard() {
console.log("[Dashboard] ran");
return <div>Dashboard</div>;
}
// Login.js
function Login() {
console.log("[Login] ran");
const { user, setUser } = useContext(AuthContext);
const inputNameRef = useRef();
return (
<div>
<input placeholder="Enter your name..." ref={inputNameRef} />
<button
onClick={() => {
setUser(inputNameRef.current.value);
}}
>
Submit
</button>
</div>
);
}
When the code runs for the first time the output is:
[App] ran
[Dashboard] ran
[Login] ran
and when the submit button is clicked, the setUser function will be called and a new value will be set to the AuthProvider state. The provider should rerender all of the components, and the above output should again be logged but nope, the output is just:
[Login] ran
Something that is interesting to me is that when I use useContext in the Dashboard component it works, I mean the component will be rerendered. It's related to the useContext hook I think but don't know how it works. What is going on under the hood?