I find it difficult to understand one point: setState in ParentComponent trigger re-rendering of ChildComponent as expected, thats ok. But setState in MyProvider component does not trigger it! Why that? There is no any memoization. You can try this story and make sure there will only 2 render messages: initial and after 6 seconds.
import React, { useEffect, useState } from "react";
const Context = React.createContext<number>(123);
const MyProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [, setProviderState] = useState(0);
useEffect(() => {
setTimeout(() => setProviderState(123), 2000);
}, []);
return <Context.Provider value={123}>{children}</Context.Provider>;
};
export const ParentComponent: React.FC = () => {
const [, setParentState] = useState(0);
useEffect(() => {
setTimeout(() => setParentState(123), 6000);
}, []);
return (
<MyProvider>
<ChildComponent />
</MyProvider>
);
};
const ChildComponent: React.FC = () => {
console.log("render!");
return <div>rest tree</div>;
};
export default { title: "Test" };
CodePudding user response:
From here:
All consumers that are descendants of a Provider will re-render whenever the Provider’s value prop changes
To trigger the re-render from provider, ensure that you change your value prop to be the state value (not the hardcoded value 123) like so:
const MyProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [providerState, setProviderState] = useState(0);
useEffect(() => {
setTimeout(() => setProviderState(123), 2000);
}, []);
return <Context.Provider value={providerState}>{children}</Context.Provider>;
};
Note the value of value
, in <Context.Provider>
is changed from being the hardcoded value of 123 to the value that providerState points to.
CodePudding user response:
useEffect(() => {
setTimeout(() => setParentState(123), 6000);
}, [setProviderState]);
Put your set state inside [] as shown in the code above. Whenever your set state changes, it will re render.