react hooks

额外的 Hook 大部分为性能优化所提供

  • 优化需要成本
  • 过度的优化只会让性能变得更差
  • 避免为了测试学习而使用额外的 hook

useEffect

1
useEffect(didUpdate: function, conditions: Array);

useEffect 内部调用的函数,应该在 useEffect 函数内部声明,以避免BUG 发生

useState

当创建的 state 并不发生昂贵的计算时

1
const [count, setCount] = useState(0);

当发生昂贵的计算时,因使用函数来返回需要的值,这样一来 react 仅会在首次渲染时调用这个函数

1
const [rows, setRows] = useState(() => createRows(props.count));

详情请参考如何惰性创建昂贵的对象?

useMemo

你可以把 useMemo 作为一种性能优化的手段,但不要把它当做一种语义上的保证。

useMemo 也允许你跳过一次子节点的昂贵的重新渲染:

1
2
3
4
5
6
7
8
9
10
11
12
function Parent({ a, b }) {
// Only re-rendered if `a` changes:
const child1 = useMemo(() => <Child1 a={a} />, [a]);
// Only re-rendered if `b` changes:
const child2 = useMemo(() => <Child2 b={b} />, [b]);
return (
<>
{child1}
{child2}
</>
);
}

详细请参考: 如何记忆计算结果?

hooks 如何避免向下传递回调?

详细请参考: 如何避免向下传递回调?

useRef 的应用

何时使用 refs?

避免使用 refs 来做任何可以通过声明式实现来完成的事情。

举个例子,避免在 Dialog 组件里暴露 open()close() 方法,最好传递 isOpen 属性。

  • 管理焦点,文本选择或媒体播放。
  • 触发强制动画。
  • 集成第三方 DOM 库。

hook 的方式和 class 的方式区别:

class:

hooks:

1
2
3
4
5
6
7
8
9
10
11
12
13
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` 指向已挂载到 DOM 上的文本输入元素
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}

使用 ref 时自定义暴露给父组件的实例值

useImperativeHandle

1
2
3
4
5
6
7
8
9
10
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);

在本例中,渲染 <FancyInput ref={inputRef} /> 的父组件可以调用 inputRef.current.focus()

useLayoutEffect 的使用场景

  • 非服务端渲染
  • useEffect 出问题的时候再尝试使用

官方详解

useCallback 使用场景

useCallback并非避免重新创建内部函数的工具

有一篇不错的经验者的文章,如果想了解详细可以参考

因为函数式组件每次重新渲染也会重新创建内部创建的方法,所以向下传递给的子组件因为props的变化而发生重新渲染(期待的情况是,仅函数内部依赖值发生变化时重新创建并向下传递)

useCallbackReact.memo一般同时使用,来避免组件内部渲染时,非必要的子组件重新渲染

#

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×