使用React Hooks的好处
-
可以在不使用class的情况下定义状态
-
方便复用
-
通过useEffect可以允许我们按照代码的用途分离它们,而不用在生命周期中,将相关的逻辑放到不同的生命周期中。
-
Effect会在每次更新时都会运行(避免了使用class组件时忘记正确的处理
componentDidUpdate
) -
可传递数组作为
useEffect
的第二个可选参数便可以只在传的数组变化时才执行,提升性能 -
清爽的代码风格+代码量更少
class Example{
hello: string;
constructor(){
this.hello = 'hello world'
}
}
// 代码量更少
function Example(){
const hello:string = 'hello world'
}
使用React Hooks的坏处
- 大量闭包导致问题错误
- 响应式的useEffect,当useEffect依赖某个函数的不可变性,这个函数的不可变性又依赖于另一个函数的不可变性,这样便形成了一条依赖链。一旦这条依赖链的某个节点意外地被改变了,你的useEffect就被意外地触发了,如果你的useEffect是幂等的操作,可能带来的是性能层次的问题,如果是非幂等,那就糟糕了
- 状态不同步(当我们有异步操作的时候,经常会碰到异步回调的变量引用是之前的,也就是旧的(这里也可以理解成闭包))——可用useRef来调用
// 状态不同步
import React, { useState } from "react";
const Counter = () => {
const [counter, setCounter] = useState(0);
const onAlertButtonClick = () => {
setTimeout(() => {
alert("Value: " + counter);
}, 3000);
};
return (
<div>
<p>You clicked {counter} times.</p>
<button onClick={() => setCounter(counter + 1)}>Click me</button>
<button onClick={onAlertButtonClick}>
Show me the value in 3 seconds
</button>
</div>
);
};
export default Counter;
// 使用useRef()
import React, { useState, useRef, useEffect } from "react";
const Counter = () => {
const [counter, setCounter] = useState(0);
const counterRef = useRef(counter);
const onAlertButtonClick = () => {
setTimeout(() => {
alert("Value: " + counterRef.current);
}, 3000);
};
useEffect(() => {
counterRef.current = counter;
});
return (
<div>
<p>You clicked {counter} times.</p>
<button onClick={() => setCounter(counter + 1)}>Click me</button>
<button onClick={onAlertButtonClick}>
Show me the value in 3 seconds
</button>
</div>
);
};
export default Counter;
如何避免React Hooks的常见问题?
- 不要在
useEffect
里面写太多的依赖项,将这些依赖项划分成多个单一功能的useEffect
。使其遵循设计模式中的“单一职责模式” - 当碰到状态不同步的问题时,可以采用手动传递参数到函数或者上面的
useRef
。
// showCount的count来自父级作用域
const [count,setCount] = useState(xxx);
function showCount(){ console.log(count) }
// showCount的count来自参数
const [count,setCount] = useState(xxx);
function showCount(c){ console.log(c) }
- 重视
eslint-plugin-react-hooks
插件的警告 - 当业务比较复杂时,使用
Component
代替hooks
将hooks 和 Component组件 混合使用,简单的业务可以使用hooks,更易维护复用,代码量少,复杂的业务,为了避免出现意想不到的问题,可以使用Component