Reputation: 5688
I have 2 actions in redux (both async) and I'm calling them both within my functional component via dispatch
; the first using useEffect
and the second via a button click. What I want to do is dispatch the actions to retrieve them from an async function, then use them within my component via useState
. But using the useState
is not rendering.
Here is my component:
export default function Hello()
{
const { first, second } = useSelector(state => state.myReducer);
const dispatch = useDispatch();
const fetchFirst = async () => dispatch(getFirst());
const fetchSecond = async () => dispatch(getSecond());
const fetchFixturesForDate = (date: Date) => dispatch(getFixturesForDate(date));
const [superValue, setSuperValue] = useState('value not set');
useEffect(() => {
const fetch = async () => {
fetchFirst();
setSuperValue(first);
};
fetch();
}, []);
const getSecondOnClickHandler = async () =>
{
console.log('a')
await fetchSecond();
setSuperValue(second);
}
return (
<div>
<p>The super value should first display the value "first item" once retrieved, then display "second value" once you click the button and the value is retrieved</p>
<p>Super Value: {superValue}</p>
<p>First Value: {first}</p>
<p>Second Value: {second}</p>
<button onClick={async () => await getSecondOnClickHandler()}>Get Second</button>
</div>
)
}
The superValue
never renders even though I am setting it, although the value from first
and second
is retrieved and displayed.
Any help?
Upvotes: 0
Views: 520
Reputation: 1726
The value of first
and second
inside your two useEffects
is set when the component mounts (I guess at that point they are undefined). So in both cases you will be setting superValue
to that initial value.
You have two options:
fetchFirst
and fetchSecond
, so that you can retrieve them directly from the executed function, and then set superValue: useEffect(() => {
const fetch = async () => {
const newFirst = await fetchFirst();
setSuperValue(newFirst);
};
fetch();
}, []);
useEffect
s that listen for changes to first
and second
useEffect(() => {
setSuperValue(first)
},[first])
useEffect(() => {
setSuperValue(second)
},[second])
Upvotes: 1
Reputation: 7554
The value in the reducer is not necessarily set when the action is dispatched, e.g. after fetchFirst()
is called. Also the await
that you do in await fetchSecond();
doesn't help since the reducer function is not executed.
You could add useEffect
hooks and remove the setSuperValue
from the other methods, but I think the code gets quite complicated.
What problem are you trying to solve in the first place?
useEffect(() => setSuperValue(first), [first]);
useEffect(() => setSuperValue(second), [second]);
useEffect(() => {
const fetch = async () => {
fetchFirst();
};
fetch();
}, []);
const getSecondOnClickHandler = async () => {
console.log('a');
await fetchSecond();
};
https://stackblitz.com/edit/react-ts-hsqd3x?file=Hello.tsx
Upvotes: 1