Hooks 是 React 实现组件逻辑的重要方式, 可以用来操作 state, 定义副作用, 更支持开发者自定义 Hooks.
React 对 UI 的理想模型是 UI=f(state), 其中 UI 是视图, state 是应用状态, f 则是渲染过程. 比起类组件, 函数组件更加贴近这一模型.
参考
- React Hooks (上): 为什么说在 React 中函数组件和 Hooks 是绝配?
- React Hooks (下): 用 Hooks 处理函数组件的副作用
- 代码复用: 如何设计开发自定义 Hooks 和高阶组件?
渲染阶段和提交阶段
useState
import React, { useState } from 'react';
// ...省略
function App() {
const [showAdd, setShowAdd] = useState(false);
// ------- ---------- -----
// ^ ^ ^
// | | |
// state变量 state更新函数 state初始值
const [todoList, setTodoList] = useState([/* ...省略 */]);
useEffect
副作用就是让一个函数不再是纯函数的各类操作,
用法:
-
只传入一个没有返回值的副作用回调函数 (Effect Callback)
useEffect(() => {}); // -------- // ^ // | // 副作用回调函数 -
副作用的条件执行
传入依赖值数组 (Dependencies) 作为第二个参数
useEffect(() => {}, [var1, var2]); // -------- ----------- // ^ ^ // | | // 副作用回调函数 依赖值数组 -
同时定义副作用回调函数, 清除函数和依赖值数组
useEffect(() => {/* 省略 */; return () => {/* 省略 */};}, [status]); // ------------------------------------------ ------- // ^ ----------------- ^ // | ^ | // 副作用回调函数 清除函数 依赖值数组
useRef
const Component = () => {
const myRef = useRef(null);
// ----- ----
// ^ ^
// | |
// 可变ref对象 可变ref对象current属性初始值
// 读取可变值
const value = myRef.current;
// 更新可变值
myRef.current = newValue;
return <div></div>;
};
useMemo 和 useCallback
useMemo 和 useCallback 都用于组件性能优化.
useEffect 在提交阶段执行, useMemo 和 useCallback 在渲染阶段执行, 它们的第二个参数都是依赖值数组.
useMemo:
const memoized = useMemo(() => createByHeavyComputing(a, b), [a, b]);
// -------- ---------------------------------- ------
// ^ ^ ^
// | | |
// 工厂函数返回值 工厂函数 依赖值数组
useCallback:
const memoizedFunc = useCallback(() => {}, [a, b]);
// ------------ -------- -----
// ^ ^ ^
// | | |
// 记忆化的回调函数 回调函数 依赖值数组
useCallback 相当于 useMemo 的另一个马甲
const memoizedFunc = useMemo(() => () => {}, [a, b]);
// ------------ -------------- -----
// ^ ^ -------- ^
// | | ^ |
// 工厂函数返回的回调函数 工厂函数 回调函数 依赖值数组