Hook

useState

const [state, setState] = useState(initialState);

返回一个 state,以及更新 state 的函数。

在初始渲染期间,返回的状态 (state) 与传入的第一个参数 (initialState) 值相同。

setState 函数用于更新 state。它接收一个新的 state 值并将组件的一次重新渲染加入队列。就是说每次使用setState都会重新渲染组件。

setState(newState);

在后续的重新渲染中,useState 返回的第一个值将始终是更新后最新的 state。

注意:

React 会确保 setState 函数的标识是稳定的,并且不会在组件重新渲染时发生变化。这就是为什么可以安全地从 useEffectuseCallback 的依赖列表中省略 setState

useEffect

useEffect(didUpdate);

重点:

  1. 赋值给 useEffect 的函数会在组件渲染到屏幕之后执行。

  2. 清除 effect:useEffect 函数可以返回一个清除函数,用以清除 effect 创建的诸如订阅或计时器 ID 等资源,示例:

    export const useDebounce = <V>(value: V, delay: number = 1000) => {
      const [debouncedValue, setDebouncedValue] = useState(value);
      useEffect(() => {
        // 每次在value变化以后,设置一个定时器
        const timeout = setTimeout(() => setDebouncedValue(value), delay);
        // 每个定时器的名称都是timeout,所以只有最后一个定时器能存活下来
        return () => clearTimeout(timeout); // 返回一个清除函数
      }, [value, delay]);
      return debouncedValue;
    };

    如果该 useEffect 只调用一次,清除函数会在组件卸载前执行;如果组件多次渲染(通常如此),则 在执行下一个 effect 之前,上一个 effect 就已被清除

  3. effect 的执行时机:传给 useEffect 的函数会在浏览器完成布局与绘制之后,在一个延迟事件中被调用,虽然 useEffect 会在浏览器绘制后延迟执行,但会保证在任何新的渲染前执行。在开始新的更新前,React 总会先清除上一轮渲染的 effect。

  4. effect 的条件执行:给 useEffect 传递第二个参数,它是 effect 所依赖的值数组。

useContext

React.createContext

const MyContext = React.createContext(defaultValue);

创建一个 Context 对象。

Context.Provider

<MyContext.Provider value={/* 某个值 */}>

Provider 接收一个 value 属性,传递给 consumers 组件。一个 Provider 可以和多个 consumers 组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。

当 Provider 的 value 值发生变化时,它内部的所有 consumers 组件都会重新渲染。

通过新旧值检测来确定变化,使用了与 Object.is 相同的算法(基本等同于“===”)。

注意

当传递对象给 value 时,检测变化的方式会导致一些问题:详见注意事项

Class.contextType

Context.Consumer

Context.displayName