当你的react项目不大,但是需要组件之间传值的时候,父子之间的组件传值倒是可以简单解决,可是如果要是兄弟之间的组件传值呢?redux又没必要,这个时候就可以使用usecontext这个hook来解决。并且可以用useReducer管理包含多个子值的 state 对象。(模拟一个小型redux场景,而无法替代redux)
一、useContext和useReducer
1、useContext:
useContext可以帮助我们跨越组件层级直接传递变量,实现数据共享。就是对它所包含的组件树提供全局共享数据的一种技术。
使用步骤:
(1)、创建context(父组件)
const CountContext = createContext("初值");
(2)、 使用CountContext.Provider包裹要传值的子组件,并且使用value传递。
<CountContext.Provider value={count}> <Counter />//可有多个兄弟组件 </CountContext.Provider>
(3)、子组件使用useContext接受
const count = useContext(CountContext);
这样子count就可以传递到各个子组件中了。
2、useReducer
useState 的替代方案。它接收一个形如
(state, action) => newState
的 reducer,并返回当前的 state 以及与其配套的dispatch
方法。(如果你熟悉 Redux 的话,就已经知道它如何工作了。)
第一个参数:reducer函数(state中的值变化时触发的函数,返回新的state)。第二个参数:初始化的state。返回值为最新的state和dispatch函数(用来触发reducer函数,计算对应的state)。按照官方的说法:对于复杂的state操作逻辑,嵌套的state的对象,推荐使用useReducer。
// 官方 useReducer Demo
// 第一个参数:应用的初始化
const initialState = {count: 0};
// 第二个参数:state的reducer处理函数
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
// 返回值:最新的state和dispatch函数
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
// useReducer会根据dispatch的action,返回最终的state,并触发rerender
Count: {state.count}
// dispatch 用来接收一个 action参数「reducer中的action」,用来触发reducer函数,更新最新的状态
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
</>
);
还有个第三个参数:惰性初始化参数:(这样第二个参数传值时做一些标准化)
function init(initialCount) { return {count: initialCount};}//initialCount时第二个参数
二、两者的结合使用
<CountContext.Provider value={{dispatch}}> <...> <LoginButton /> </CountContext.Provider>