I have to react variable, let's call it temp
, it's not a state variable but a normal let variable.
the problem is that I am not able to get the updated value in the render. I know it's not a state variable so it won't rerender the UI, whenever the variable is updated.
but, I am not accessing the variable until the variable is set.
ex: ->
const MyComponent = (props) => {
let temp;
const [loading, setLoading] = useState(true);
init = () => {
setLoading(true);
temp = "updated value";
setLoading(false);
}
useEffect(() => {
init();
}, [])
return (
{laoding ? <div>loading</div> : <div> {temp}</div>}
)
}
in the above code, if the loading is false and the temp variable is set, then the UI should reflect the updated value. but, it's not,
it works fine in-class components.
am I missing something here?
CodePudding user response:
You can utilize the effect for the functional components. useEffect
gets triggered every time its dependency changes which will trigger rerender for you.
However, I can't see the real use of the init variable. So assuming you want to set value during component mount. I think it'll look like the below.
const MyComponent = (props) => {
let temp;
const [loading, setLoading] = useState(true);
useEffect(() => {
// Empty array means that this will be executed when component mounts
init()
}, [])
useEffect(() => {
// Rerender will be triggered whenever temp gets changed
}, [temp])
const init = () => {
setLoading(true);
temp = "updated value";
setLoading(false);
}
return (
<>
{
loading ? <span>loading...</span> : <span>{temp}</span>
}
</>
)
}
NOTE: I'd still go with storing temp as a state in this case because it's the part of react's system and that's how it should be used.
CodePudding user response:
the execution here is: component renders => mounts => use effect runs => state is changed => rerenders => temp is newly created as undefined let. use useRef
for temp and assign temp.current = ...
in init. it guarantees to persist through renders.
const MyComponent = (props) => {
const temp = useRef();
const [loading, setLoading] = useState(true);
const init = () => {
setLoading(true);
temp.current = "updated value";
setLoading(false);
};
useEffect(() => {
init();
}, []);
return <>{loading ? <div>loading</div> : <div>{temp.current}</div>}</>;
};