如何在React中使用带有钩子的生命周期方法?

时间:2018-11-08 19:01:17

标签: javascript reactjs react-native react-hooks

我经历了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>
   );
  }

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

4 个答案:

答案 0 :(得分:10)

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

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的语义。这answer is by 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的callback参数中返回一个回调,它将在卸载前被调用。

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.PureComponentReact.memo在组件级别实现此目的。为了防止子组件的重新呈现,此示例摘自React docs

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 docs

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

还没有等效的钩子。

答案 1 :(得分:2)

嗯,您实际上没有生命周期方法。 =)但是您可以使用效果钩子,如下所示:https://reactjs.org/docs/hooks-effect.html

效果钩子将能够复制componentDidMount,componentDidUpdate和componentWillUnmount的行为

因此,您实际上不需要组件中的生命周期方法。效果钩代替了它们。 =)

阅读上面的链接,您将获得一些有关它们如何工作的示例。

答案 2 :(得分:2)

React团队为此提供了一个useEffect钩子。让我们以示例中的组件为例,并添加服务器上载以进行计数,否则我们将其放入例如componentDidUpdate

 import { useState, useEffect } from 'react';

 function Example() {
   const [count, setCount] = useState(0);
   useEffect(() => {
     fetch(
       'server/url',
       {
         headers: {
           'Accept': 'application/json',
           'Content-Type': 'application/json'
         },
         body: JSON.stringify({count}),
       }
     ); 
   });

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

在本例中,这似乎不是一个巨大的胜利,因为事实并非如此。但是生命周期方法的问题在于,您只能在组件中获得其中一种。如果要上载到服务器并触发事件,然后将消息放入队列,而这些都没有关系怎么办?太糟糕了,他们全都塞在componentDidUpdate中。或者,您有n层包装的HOC,可以用于您想做的n件事情。但是,有了钩子,您可以将所有这些拆分成对useEffect的解耦调用,而无需不必要的HOC层。

答案 3 :(得分:1)

功能组件是纯粹的无状态组件。但是在React 16.8中,他们添加了Hooks。可以使用挂钩代替状态和生命周期方法。

是的,您可以想到 useEffect 像赞似的

  • componentDidMount

  • componentDidUpdate

  • componentWillUnmount

  • shouldComponentUpdate 组合。

  • 注意:它是 componentDidMount componentDidUpdate componentWillUnmount&shouldComponentUpdate < / p>