I have a piece of state that is async generated and is changed based on another piece of async state. I can get the updated prop of the state that i set in the child but not the other that is async generated in the parent. Hard to explain, but here is an example i made.
app.tsx
import { useEffect, useState } from 'preact/hooks';
import { Child } from './Child';
import "./app.css"
export function App() {
const [count, setCount] = useState(0);
const [otherState, setOtherState] = useState(0);
useEffect(() => {
const asycSetState = async () => {
setTimeout(() => {
setOtherState(count + 100);
}, 1000);
};
}, [count, otherState]);
return (
<>
<Child count={count} setCount={setCount} otherState={otherState} />
</>
);
}
Child.tsx
export const Child = ({ count, setCount, otherState }) => {
return (
<>
<div>count: {count}</div>
<button
onClick={() => {
setCount(count + 1);
}}
>
add
</button>
<h3>otherstate: {otherState}</h3>
</>
);
};
So in this example the Child will properly render the count but otherstate is not.
I have made a Stackblitz Here
Ok. That was my mistake. This example above works when you invoke asyncSetState(). I cannot replicate the problem i am having and i can't really post my actual project. But here is a small snip.
selectedRace is the state being changed in the child an tableData and raceName are updated in the parent
...
useEffect(() => {
(async () => {
const result = await makeTableData();
setTableData(result);
})();
}, [compsCol, selectedRace]);
useEffect(() => {
if (!raceLoading) {
(async () => {
const name = await raceDoc?.name;
console.log("name: ", name);
setRaceName(name);
})();
}
}, [raceDoc]);
const data = useMemo(() => {
return tableData;
}, [tableData]);
...
<Fragment>
{console.log("index: ", raceName)}
<FleetsTables
raceName={raceName}
setRaceName={setRaceName}
tableData={tableData}
serInfo={serInfo}
setSelectedRace={setSelectedRace}
selectedRace={selectedRace}
{...rest}
/>
</Fragment>
So in this snippet the console will log out the new raceName (state) i am looking for, but in the FleetsTables component the state of raceName never changes.
I would add that the updating tableData state should take longer than raceName and it does correctly update in the children.
SO obviously there is not enough context to fix my code, but WHAT can be possible reasons for something like this to happen. I have tried everything i can think of with no luck.
Really simple issue: you never actually call asycSetState
.
useEffect(() => {
const asycSetState = async () => {
setTimeout(() => {
setOtherState(count + 100);
}, 1000);
};
+ asycSetState();
}, [count, otherState]);
Could also make that into an IIFE:
useEffect(() => {
(async () => {
setTimeout(() => {
setOtherState(count + 100);
}, 1000);
})();
}, [count, otherState]);
You should also remove otherState
from the deps array. Your code will create an infinite loop, as you're setting otherState
then the effect re-fires as a result.