[React] When to useReducer instead of useState
React to of when instead
2023-09-14 09:00:47 时间
useState
is typically simpler at first than useReducer
(you can even implement useState
using useReducer
), but there's one scenario where useReducer
is almost certainly better than useState
:
When one element of your state relies on the value of another element of your state in order to update:
useReducer
More information: KcD's blog
import React from 'react' import ReactDOM from 'react-dom' function undoReducer(state, action) { const {past, present, future} = state const {type, newPresent} = action switch (type) { case 'UNDO': { if (past.length === 0) return state const previous = past[past.length - 1] const newPast = past.slice(0, past.length - 1) return { past: newPast, present: previous, future: [present, ...future], } } case 'REDO': { if (future.length === 0) return state const next = future[0] const newFuture = future.slice(1) return { past: [...past, present], present: next, future: newFuture, } } case 'SET': { if (newPresent === present) { return state } return { past: [...past, present], present: newPresent, future: [], } } case 'RESET': { return { past: [], present: newPresent, future: [], } } default: { throw new Error(`Unhandled action type: ${type}`) } } } function useUndo(initialPresent) { const [state, dispatch] = React.useReducer(undoReducer, { past: [], present: initialPresent, future: [], }) const canUndo = state.past.length !== 0 const canRedo = state.future.length !== 0 const undo = React.useCallback(() => { dispatch({type: 'UNDO'}) }, []) const redo = React.useCallback(() => { dispatch({type: 'REDO'}) }, []) const set = React.useCallback(newPresent => { dispatch({type: 'SET', newPresent}) }, []) const reset = React.useCallback(newPresent => { dispatch({type: 'RESET', newPresent}) }, []) return [state, {set, reset, undo, redo, canUndo, canRedo}] } function App() { const [state, {set}] = useUndo('first') React.useEffect(() => { set('second') }, [set]) React.useEffect(() => { set('third') }, [set]) return <pre>{JSON.stringify(state, null, 2)}</pre> } ReactDOM.render(<App />, document.getElementById('root'))
相关文章
- [Web] How to Test React and MobX with Jest
- [Web 前端] React Router v4 入坑指南
- [Reac] React 18
- [React] When to useReducer instead of useState
- [React + GraphQL] Use useLazyQuery to manually execute a query with Apollo React Hooks
- [React + Functional Programming ADT] Connect State ADT Based Redux Actions to a React Application
- [React] Integration test a React component that consumes a Render Prop
- [Recompose] Create Stream Behaviors to Push Props in React Components with mapPropsStream
- [React Router v4] Intercept Route Changes
- [React] useImperativeHandle, similar to Angular Directive `exportAs`
- [React Testing] Use React Testing Library to Render and Test Simple React Components
- [React] Use React.ReactNode for the children prop in React TypeScript components and Render Props
- [React + Functional Programming ADT] Connect State ADT Based Redux Actions to a React Application
- [React] Refactor a Stateful List Component to a Functional Component with React PowerPlug
- [Recompose] Stream Props to React Children with RxJS
- [React & Debug] Quick way to debug Stateless component
- [React Router v4] Style a Link that is Active with NavLink
- [React] Recompose: Theme React Components Live with Context
- 三种Web前端框架比较与介绍--Vue, react, angular
- 如何在React项目中使用ECharts图表库
- React里require('object-assign')里的实现原理