useReducer 用法:
const [state, dispatch] = useReducer(reducer, initState, init?);
其中,initialArg 为初始值(必传),init 为初始函数(可选)。
- 当没有 init 参数时,state的初始值为 initState;
- 当有 init 参数时,state的初始值为 init(initState) 返回的值
当然,initialArg 也可以是调用函数 得到的返回值,如
const [state, dispatch] = useReducer(reducer, initState(1));
这种情况下,如果组件频繁重新渲染(比如当前组件是一个输入框,输入内容变更,组件也会跟着更新),那么每次渲染都会调用 initState
函数,导致性能变差。
想要避免上边的性能问题,可以借用 useReducer 的第三个参数:
const [state, dispatch] = useReducer(reducer, 1, initState);
和上边相比,这里是给useReducer 传了3个参数:
- reducer:reducer函数,没变化;
- 1: 初始值;
- initState: 初始化函数;
此时,state = initState(1);
这个示例使用了一个初始化函数 initState,所以 initState 函数只会在初次渲染的时候进行调用。即使往输入框中输入内容导致组件重新渲染,初始化函数也不会被再次调用。
代码及演示如下:
1. 调用函数获取初始值:
const [state, dispatch] = useReducer(reducer, initState(0) );
完整代码:
import { useReducer, useState } from "react"
function reducer(state, action) {
switch(action.type) {
case 'increase':
return state + 1;
case 'decrease':
return state - 1;
default:
throw new Error()
}
}
export default function App() {
const [state, dispatch] = useReducer(reducer, initState(0) );
return (
<>
<button onClick={() => dispatch({type: 'increase'})}>+</button>
<span>{state}</span>
<button onClick={() => dispatch({type: 'decrease'})}>-</button>
</>
)
}
function initState(state) {
console.log('initState');
return state + 100;
}
效果:
2. 使用初始化函数
重点代码:
const [state, dispatch] = useReducer(reducer, 0, initState );
完整代码:
import { useReducer, useState } from "react"
function reducer(state, action) {
switch(action.type) {
case 'increase':
return state + 1;
case 'decrease':
return state - 1;
default:
throw new Error()
}
}
export default function App() {
const [state, dispatch] = useReducer(reducer, 0, initState );
return (
<>
<button onClick={() => dispatch({type: 'increase'})}>+</button>
<span>{state}</span>
<button onClick={() => dispatch({type: 'decrease'})}>-</button>
</>
)
}
function initState(state) {
console.log('initState');
return state + 100;
}
效果: