Dispatch inside useEffect does not update state the first time
pongsatt opened this issue · comments
Problem: global state does not update when dispatch from inside useEffect the first time.
Example:
import * as React from 'react';
import { createStore } from 'react-hooks-global-state';
type State = { items: string[], loading: boolean }
type Action = { type: 'loadItems', items: string[] }
| { type: 'loading', loading: boolean };
const reducer = (state: State, action: Action) => {
switch (action.type) {
case 'loadItems': return { ...state, items: action.items }
case 'loading': return { ...state, loading: action.loading }
default: return state;
}
}
const initialState: State = { items: [], loading: false };
const { GlobalStateProvider, useGlobalState, dispatch } = createStore(reducer, initialState);
const loadInitialCount = async () => {
dispatch({type: 'loading', loading: true});
return new Promise<string[]>(resolve => setTimeout(() => resolve(['item1', 'item2']), 3000))
.then(items => {
dispatch({type: 'loading', loading: false});
dispatch({type: 'loadItems', items});
});
}
const ItemList = () => {
const [items] = useGlobalState('items');
const [loading] = useGlobalState('loading');
React.useEffect(() => {
loadInitialCount();
}, []);
if (loading) return <span>Loading...</span>;
return (
<>
<button onClick={loadInitialCount}>reload</button>
<ul>
{items.map(item => <li key={item}>{item}</li>)}
</ul>
</>
);
};
export default () => {
return (
<GlobalStateProvider>
<ItemList />
</GlobalStateProvider>);
};
When "loadInitialCount()" is called the first time, "Loading..." won't show up. But it's shown when click "reload" button.
I found that this is because "GlobalStateProvider" registers listener inside "useEffect" which is called after "useEffect" of "ItemList" component . So the "loading" state is not updated the first time.
@pongsatt Good catch! I confirmed the issue.
@pongsatt Published v0.4.0. Thanks for reporting!