I have a functional component and want to update some state in that component (based on some context API object value i.e. I get via useContext)
Now, I see 2 options;
- Using local variable
- Using setState
I just wanted to understand the difference between the 2 ways. Also to add, when using setState, I run into below issue Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
Just to add, this functional component is a direct child of App component and the context object is updated in another component which is also a direct child of App component.
const MyComponent = () => {
let myTitle = "ABC"; //Option 1 to use 'myTitle'
//const [myTitle, setMyTitle] = useState('ABC'); //Option 2 to use 'myTitle'
if (someContextApiObj.value === "XYZ") {
myTitle = "XYZ";
//setMyTitle("XYZ")
}
return (
<>
<ChildComponent
myTitle={myTitle}
/>
</>
);
};
export default MyComponent;
CodePudding user response:
Your code runs into an infinite loop because of your if-clause. If you set the title and the condition doesn't change, it will get set on every rerender causing a new render - infinite chain of rerenders.
Using a state offers you the ability to change the value conditionally, while using a local variable not coupled to a state makes the variable constant.
CodePudding user response:
You should use the Hook useEffect.
const MyComponent = () => {
const [myTitle, setMyTitle] = useState('ABC'); //Option 2 to use 'myTitle'
useEffect(()=> {
if (someContextApiObj.value === "XYZ") {
setMyTitle("XYZ")
}
}, []);
return (
<>
<ChildComponent
myTitle={myTitle}
/>
</>
);
};
export default MyComponent;
CodePudding user response:
It seems you are wanting to compute a myTitle
value based on some prop or context value being passed to the component. Storing passed props/context values in local state is generally considered anti-pattern in React. Compute the myTitle
value and pass it along to the child component.
const MyComponent = () => {
const myTitle = someContextApiObj.value === "XYZ" ? "XYZ" : "ABC";
return <ChildComponent myTitle={myTitle} />;
};
If the myTitle
value is an expensive calculation or you just want to provide a stable reference to children, use the useMemo
hook to provide this.
import { useMemo } from 'react';
const MyComponent = () => {
const myTitle = useMemo(() => {
return someContextApiObj.value === "XYZ" ? "XYZ" : "ABC";
}, [someContextApiObj]);
return <ChildComponent myTitle={myTitle} />;
};