useReducer's dispatch should return a promise which resolves once its action has been delivered
(This is a spinoff from [this thread](https://github.com/facebook/react/issues/15240).) It's sometimes useful to be able to dispatch an action from within an async function, wait for the action to transform the state, and then use the resulting state to determine possible further async work to do. For this purpose it's possible to define a `useNext` hook which returns a promise of the next value: ```js function useNext(value) { const valueRef = useRef(value); const resolvesRef = useRef([]); useEffect(() => { if (valueRef.current !== value) { for (const resolve of resolvesRef.current) { resolve(value); } resolvesRef.current = []; valueRef.current = value; } }, [value]); return () => new Promise(resolve => { resolvesRef.current.push(resolve); }); } ``` and use it like so: ```js const nextState = useNext(state); useEffect(() => { fetchStuff(state); }, []); async function fetchStuff(state) { dispatch({ type: 'START_LOADING' }); let data = await xhr.post('/api/data'); dispatch({ type: 'RECEIVE_DATA', data }); // get the new state after the action has taken effect state = await nextState(); if (!state.needsMoreData) return; data = await xhr.post('/api/more-data'); dispatch({ type: 'RECEIVE_MORE_DATA', data }); } ``` This is all well and good, but `useNext` has a fundamental limitation: it only resolves promises when the state _changes_... so if dispatching an action resulted in the same state
Posted by pelotom on Apr 7, 2019, 12:04 AM
Tags
Related issues
- [Meta] Feedback on granular control over Copilot changes
- unexpected status 401 Unauthorized issue
- [MODEL] Measurable quality regression in Claude generation 5 (Fable 5 / Opus 5 / Sonnet 5): worse nonsense detection, ~2x verbosity, under-disclosed model fallb
- [CRITICAL] Subagent spawning and subagent pattern bugs trigger infinite recursion, infinite token usage, grossly inefficient token usage, and lost accumulated s
- Video stops playing after some minutes
- [MODEL] Claude verbose code comments by default — ignores instructions to stop.
Raise real-world problems, find people facing the same issue, and discuss solutions.4,000 issues0 comments
github (Software)
[Meta] Feedback on granular control over Copilot changes
unexpected status 401 Unauthorized issue
[MODEL] Measurable quality regression in Claude generation 5 (Fable 5 / Opus 5 / Sonnet 5): worse nonsense detection, ~2x verbosity, under-disclosed model fallb
[CRITICAL] Subagent spawning and subagent pattern bugs trigger infinite recursion, infinite token usage, grossly inefficient token usage, and lost accumulated s
Video stops playing after some minutes
[MODEL] Claude verbose code comments by default — ignores instructions to stop.
Scope Codex VS Code chats to the current workspace/project
Update on "Co-authored-by: Copilot" in commit messages
useReducer's dispatch should return a promise which resolves once its action has been delivered
(This is a spinoff from [this thread](https://github.com/facebook/react/issues/15240).) It's sometimes useful to be able to dispatch an action from within an async function, wait for the action to transform the state, and then use the resulting state to determine possible further async work to do. For this purpose it's possible to define a `useNext` hook which returns a promise of the next value: ```js function useNext(value) { const valueRef = useRef(value); const resolvesRef = useRef([]); useEffect(() => { if (valueRef.current !== value) { for (const resolve of resolvesRef.current) { resolve(value); } resolvesRef.current = []; valueRef.current = value; } }, [value]); return () => new Promise(resolve => { resolvesRef.current.push(resolve); }); } ``` and use it like so: ```js const nextState = useNext(state); useEffect(() => { fetchStuff(state); }, []); async function fetchStuff(state) { dispatch({ type: 'START_LOADING' }); let data = await xhr.post('/api/data'); dispatch({ type: 'RECEIVE_DATA', data }); // get the new state after the action has taken effect state = await nextState(); if (!state.needsMoreData) return; data = await xhr.post('/api/more-data'); dispatch({ type: 'RECEIVE_MORE_DATA', data }); } ``` This is all well and good, but `useNext` has a fundamental limitation: it only resolves promises when the state _changes_... so if dispatching an action resulted in the same state
Comments (0)
No comments yet. Start the discussion.