useState和useReducer
![在这里插入图片描述](https://img-blog.csdnimg.cn/1d09119e005047cdbdca4a73298be25f.png
const [state的名字, 用于修改state的函数] = useState(state的初始值)
const [state的名字, 用于修改state的函数] =
useReducer((state, action) => 新的state, state的初始值)
二、useReducer 工作原理
useReducer 钩子用来存储和更新状态,在用法上,它接收一个reducer函数作为第一个参数,第二个参数是初始化的state。useReducer最终返回一个存储有当前状态值的数组和一个dispatch函数,该dispatch函数执行触发action,带来状态的变化。
1.dispatch 函数
在 React 中,派发一个动作是通过使用 store.dispatch() 方法来实现的。
store.dispatch() 接收一个 action 对象作为参数,它包含了要更新 state 的信息。
代码如下(示例):
const [state, dispatch] = useReducer(reducer, { age: 42 });
function handleClick() {
dispatch({ type: 'incremented_age' });
//...
}
该dispatch函数仅更新下一次渲染的状态变量。如果在调用该函数后读取状态变量dispatch,仍然会获得调用之前屏幕上的旧值。
在reducer函数中的state是只读的,不能进行赋值操作。
三.组件之间分享state
在某些场景想再组件之间分享state,进行全局的state管理时,我们可以使用useReducer加useContext。
当有3个子组件A, B, C,要在子组件内控制同一个计数器,常规的写法是将 counter 的方法写到父组件上,然后通过 props 的方式将 counter 方法和 state 传给子组件,子组件中调用通过 props 传入的 counter 方法,就会改变父组件中的 state,同时也能改变作为 props 传递给子组件的 app 中的 state。
但这种设计有个缺点,如果组件层级非常深的话,只能通过props一层一层地往下传,等到后期应用复杂度越来越高的时候,就很难维护,这个时候就可与使用useContext和useReducer。
// AChild
import React, {useContext} from 'react';
import {countContext} from '../App';
function A() {
const countContext = useContext(CountContext);
return (
<div>
A - {countContext.count}
<button onClick={() => countContext.dispatch('add')}>+</button>
</div>
)
}
import React, {useReducer} from 'react';
export const CountContext = React.createContext({});
const initialState = 0;
const reducer = (state, action) => {
switch(action) {
case 'add':
return state + 1;
default:
return state
}
}
const App = () => {
const [count ,dispatch] = useReducer(reducer, initialState);
return (
<CountContext.Provider
value={{
count,
dispatch
}}
>
<div>
<AChild/>
</div>
</CountContext.Provider>
)
}
总结
场景 | useState | useReducer |
---|---|---|
state的类型为number,string,boolean | 建议 | 不建议 |
state的类型为object或array | 不建议 | 建议 |
state多 | 不建议 | 建议 |
state关联变化 | 不建议 | 建议 |
state只在组件内部使用 | 建议 | 不建议 |
state全局使用 | 不建议 | 建议 |