hooks引入react里已经很长时间了,在项目中一直使用,文档也没仔细阅读,今天打算再重新看看文档,领略一下当初学习的感受。
这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
今天继续学习几个高阶的Hooks:useMemo、useRef、useReducer。
useMemo
useMemoo用于进行值的依赖更新,可以用于在每次渲染时避免昂贵的计算。如官网给的例子:
//非常昂贵的计算
function computeExpensiveValue(a,b){
let sum = 0;
for(var i = 0; i < 10000; i++ ){
sum += (a+b);
}
return sum;
}
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
//只有当a,b发送变化时才会重新计算memoizedValue
另:useMemo(()=>fn,dependencies)等于useCallback(fn,dependencies).
useRef
该Hook用于获取DOM节点的引用。现在都在用框架开发网页应用。然后有一些场景还是需要使用原生的力量:DOM操作。
举个例子:输入一些内容,点击按钮打印内容。
const Input:React.FC<{}> = ()=>{
const inputEl = React.useRef<HTMLInputElement>(null);
const onButtonClick = () => {
console.log(inputEl.current?.value);
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>获取输入内容</button>
</>
);
}
首先在使用时需要注意两点:
- DOM节点对应的元素类型。比如input输入框:
HTMLInputElement,div:HTMLDivElement,这些节点用于设置useRef的泛型。如React.useRef<HTMLInputElement> - 初始值设置为
null
useReducer
reducer,相信大家都不陌生,redux里的一个重要的概念,用于修改应用里的store数据。相信react也是借用了这个概念吧,毕竟现在React的核心开发者是redux的作者。
首先看一下它的语法结构:
const [state, dispatch] = useReducer(reducer, initialArg, init);
我们拿官方例子来说明:
const initialState = {count: 0};
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() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
其实你会发现这跟useState非常类似,都提供了state的引用和state的setter。然而对于那些复杂的数据,官方推荐使用useReducer的方式。
上面的例子里的初始state是默认声明好的,还有一种可以接收参数作为默认值的方式:
function init(initialCount) { return {count: initialCount};}
function reducer(state, action) {
//省略。。。
}
function Counter({initialCount}) {
const [state, dispatch] = useReducer(reducer, initialCount, init); return (
<>
//省略。。。
</>
);
}
最后
感谢阅读。