如何在 React 中使用带有钩子的生命周期方法? [英] How to use lifecycle methods with hooks in React?

查看:32
本文介绍了如何在 React 中使用带有钩子的生命周期方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经了解了 react v16.7.0 中引入的钩子.

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

所以我对钩子的理解是,我们可以在功能组件中处理状态,而无需在 React 中编写类组件.这真是一个了不起的功能.

但是我对在功能组件中使用钩子没有得到清楚的了解.

 import { useState } from 'react';函数示例(){const [count, setCount] = useState(0);返回 (<div><p>您点击了 {count} 次</p><button onClick={() =>setCount(count + 1)}>点击我

);}

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

解决方案

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

componentDidMount

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

function Example() {const [count, setCount] = useState(0);useEffect(() => {document.title = `您点击了 ${count} 次`;}, []);//传递一个空数组以仅在挂载时运行回调.返回 (<div><p>您点击了 {count} 次</p><button onClick={() =>setCount(count + 1)}>点击我

);}

componentDidUpdate(松散)

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

function Example() {const [count, setCount] = useState(0);useEffect(() => {document.title = `您点击了 ${count} 次`;});//没有第二个参数,所以在每次渲染后运行.返回 (<div><p>您点击了 {count} 次</p><button onClick={() =>setCount(count + 1)}>点击我

);}

componentDidUpdate(严格)

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

function Example() {const [count, setCount] = useState(0);const firstUpdate = useRef(true);useLayoutEffect(() => {如果(firstUpdate.current){firstUpdate.current = false;返回;}console.log('componentDidUpdate');});返回 (<div><p>componentDidUpdate:{count} 次</p><按钮onClick={() =>{设置计数(计数 + 1);}}>点击我

);}

componentWillUnmount

useEffect 的回调参数中返回一个回调,它会在卸载前被调用.

function Example() {const [count, setCount] = useState(0);useEffect(() => {//在 useEffect 中返回一个回调,它会在卸载前被调用.返回 () =>{console.log('componentWillUnmount!');};}, []);返回 (<div><p>您点击了 {count} 次</p><button onClick={() =>setCount(count + 1)}>点击我

);}

shouldComponentUpdate

您已经可以使用 React.PureComponentReact.memo 在组件级别实现这一点.为了防止子组件的重新渲染,这个例子取自 反应文档:

function Parent({ a, b }) {//只有在 `a` 改变时才重新渲染:const child1 = useMemo(() => , [a]);//只有在 `b` 改变时才重新渲染:const child2 = useMemo(() => , [b]);返回 (<>{child1}{child2}</>)}

getDerivedStateFromProps

同样,摘自 React 文档

function ScrollView({row}) {让 [isScrollingDown, setIsScrollingDown] = useState(false);让 [prevRow, setPrevRow] = useState(null);如果(行!== prevRow){//自上次渲染后行更改.更新是向下滚动.setIsScrollingDown(prevRow !== null && row > prevRow);setPrevRow(row);}返回`向下滚动:${isScrollingDown}`;}

getSnapshotBeforeUpdate

目前还没有钩子的等价物.

componentDidCatch

目前还没有钩子的等价物.

I have gone through hooks introduced in react v16.7.0.

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

So my understanding about hooks is we can play with state in functional component without writing class components in react. This is really amazing feature.

But I am not getting clear picture about using hooks in functional components.

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

how can I use life cycle methods in the above functional component if I use hooks?

解决方案

Here are examples for the most common lifecycles:

componentDidMount

Pass an empty array as the second argument to useEffect() to run only the callback on mount only.

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 (loose)

By passing just the single argument into useEffect, it will run after every render. This is a loose equivalent because there's a slight difference here being componentDidUpdate will not run after the first render but this hooks version runs after every render.

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 (strict)

The difference of this example with the example above is that the callback here would not run on initial render, strictly emulating the semantics of componentDidUpdate. This answer is by Tholle, all credit goes to him.

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

Return a callback in useEffect's callback argument and it will be called before unmounting.

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

You can already achieve this on the component level using React.PureComponent or React.memo. For preventing rerendering of the child components, this example is taken from 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

Again, taken from the 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

No equivalent for hooks yet.

componentDidCatch

No equivalent for hooks yet.

这篇关于如何在 React 中使用带有钩子的生命周期方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆