当前位置: 首页 > 知识库问答 >
问题:

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

越英韶
2023-03-14

我已经通过了在反应v16.7.0中引入的钩子。

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

所以我对钩子的理解是,我们可以在函数组件中使用状态,而不用在反应中编写类组件。这真是惊人的功能。

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

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

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

共有3个答案

公宜春
2023-03-14

React团队为此目的提供了一个use效应钩子。让我们以您的示例中的组件为例,为计数添加服务器上传,否则我们会将其放在例如组件didUpdate中:

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

在这个例子中,这似乎不是一个巨大的胜利,因为事实并非如此。但是生命周期方法的问题是,您只能在组件中获得其中的一个。如果你想上传到服务器,触发一个事件,把一条消息放在队列上,而这些都不相关呢?太糟糕了,它们都被塞进了组件didUpdate中。或者,您有n层包装的HOC,用于您想要做的n事情。但是有了钩子,您可以将所有这些划分为对use效应的解耦调用,而无需不必要的HOC层。

仲孙逸明
2023-03-14

嗯,您实际上没有生命周期方法但是您可以使用这里显示的效果挂钩https://reactjs.org/docs/hooks-effect.html

效果钩子将能够复制组件的行为

因此,您真的不需要组件中的生命周期方法。效果钩子取而代之。=)

阅读上面的链接,你会得到一些关于它们如何工作的例子。

伯向晨
2023-03-14

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

将一个空数组作为第二个参数传递给use效应(),以便仅在挂载上运行回调。

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

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

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

这个例子与上面的例子的不同之处在于,这里的回调不会在初始渲染时运行,严格模拟了组件的语义学。这个答案是索尔的,所有的功劳都归功于他。

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

useffect的回调参数中返回回调,在卸载之前将调用该回调。

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

您已经可以使用React在组件级别实现这一点。PureComponent反应。备忘录。为了防止子组件重新招标,此示例取自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}
    </>
  )
}

同样,摘自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}`;
}

还没有挂钩的等价物。

还没有挂钩的等价物。

 类似资料:
  • 问题内容: 随着AngularJS V1.7的发布,已经不建议使用和取消预定义绑定的选项: 由于38f8c9, 指令绑定在构造函数中不再可用 。 迁移代码: * 如果指定,则需要首先迁移代码,以便将标志翻转到。有关如何执行此操作的说明,请参见 “从1.5迁移到1.6”指南。之后,删除该语句。 — AngularJS开发人员指南- 迁移至V1.7-编译 由于bcd0d4的缘故,默认情况下在控制器实例

  • 问题内容: 我已经通过了React v16.7.0中引入的钩子。 https://reactjs.org/docs/hooks-intro.html 因此,我对钩子的理解是,我们可以在功能组件中使用状态,而无需在react中编写类组件。这真是一个了不起的功能。 但是我对在功能组件中使用钩子一无所知。 如果使用钩子,如何在上述功能组件中使用生命周期方法? 问题答案: 以下是最常见生命周期的示例: 传

  • 使用React钩子(如)的、和生命周期钩子的等价物是什么?

  • 问题内容: 我是React / Redux的新手,状态有问题。 TrajectContainer.jsx 当reducer返回新状态时,组件将使用新数据重新呈现。 但是:如果删除componentWillReceiveProps函数,则render()函数将具有旧状态。 我检查了mapStateToProps中收到的数据,这是新的新状态。所以我不明白为什么我需要componentWillRecei

  • 问题内容: 我刚刚阅读了React的新功能挂钩。了解有关钩子的信息, 但我无法使用它。它给我错误。 我目前正在使用16.6.0版 终于我明白了钩子。 我导入为Fun并在app.js文件中使用 我犯的错误是我没有安装React v16.7.0-alpha,所以我使用npm安装了add react @ next react-dom @ next。 谢谢 问题答案: 编辑: 挂钩是16.8.0版的一部分

  • 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。 比如created钩子可以用来在一个实例被创建之后执行代码: new Vue({ data: { a: 1 }, created: fu