首页 > 解决方案 > 如何在 React 中使用带有钩子的生命周期方法?

问题描述

我已经浏览了 react v16.7.0 中引入的钩子。

https://reactjs.org/docs/hooks-intro.html

所以我对钩子的理解是我们可以在函数组件中使用状态,而无需在 react 中编写类组件。这真是一个了不起的功能。

但是我没有清楚地了解在功能组件中使用钩子。

   import { useState } from 'react';

   function Example() {
   const [count, setCount] = useState(0);

    return (
      <div>
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
         Click me
        </button>
      </div>
   );
  }

如果我使用钩子,如何在上述功能组件中使用生命周期方法?

标签: javascriptreactjsreact-nativereact-hooks

解决方案


以下是最常见生命周期的示例:

componentDidMount

将一个空数组作为第二个参数传递useEffect()给仅在挂载时运行回调。

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, []); // Pass an empty array to run only callback on mount only.

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

componentDidUpdate(松动的)

通过仅将单个参数传递给useEffect,它将在每次渲染后运行。这是一个松散的等价物,因为componentDidUpdate在第一次渲染后不会运行,但这个钩子版本在每次渲染后运行。

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }); // No second argument, so run after every render.

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

componentDidUpdate(严格的)

这个例子与上面例子的不同之处在于这里的回调不会在初始渲染时运行,严格模拟componentDidUpdate. 这个答案是由 Tholle 提供的,所有功劳归他所有。

function Example() {
  const [count, setCount] = useState(0);

  const firstUpdate = useRef(true);
  useLayoutEffect(() => {
    if (firstUpdate.current) {
      firstUpdate.current = false;
      return;
    }

    console.log('componentDidUpdate');
  });

  return (
    <div>
      <p>componentDidUpdate: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

componentWillUnmount

在 的回调参数中返回一个回调,useEffect它将在卸载之前被调用。

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // Return a callback in useEffect and it will be called before unmounting.
    return () => {
      console.log('componentWillUnmount!');
    };
  }, []);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

shouldComponentUpdate

您已经可以使用React.PureComponent或在组件级别上实现此目的React.memo。为了防止子组件重新渲染,这个例子取自React 文档

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}
    </>
  )
}

getDerivedStateFromProps

同样,取自React 文档

function ScrollView({row}) {
  let [isScrollingDown, setIsScrollingDown] = useState(false);
  let [prevRow, setPrevRow] = useState(null);

  if (row !== prevRow) {
    // Row changed since last render. Update isScrollingDown.
    setIsScrollingDown(prevRow !== null && row > prevRow);
    setPrevRow(row);
  }

  return `Scrolling down: ${isScrollingDown}`;
}

getSnapshotBeforeUpdate

还没有钩子的等价物。

componentDidCatch

还没有钩子的等价物。


推荐阅读