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

等效于使用React挂钩的componentDidUpdate

丁绪
2023-03-14

太长,读不下去了如何模拟componentdiddupdate或使用带有数组的道具强制重置我的组件?

我正在实现一个组件,它显示一个计时器,并在达到零时执行回调。目的是让回调更新对象列表。后一个组件由新的React钩子useStateuse效应组成。

state包含对计时器启动时间和剩余时间的引用。效果设置每秒钟调用一次的间隔,以更新剩余的时间,并检查是否应该调用回调。

该组件并不意味着重新安排计时器,或者在间隔达到零时保持间隔,它应该执行回调并空闲。为了让计时器刷新,我希望传递一个数组给key,这将导致组件的状态被重置,因此计时器将重新启动。不幸的是key必须与字符串一起使用,因此无论我的数组的引用是否已更改,都不会产生任何影响。

我还试图通过传递我所关心的数组来推动道具的变化,但状态保持不变,因此间隔没有重置。

为了强制仅使用新的hooks API更新状态,观察数组中的浅层变化的首选方法是什么?

import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';

function getTimeRemaining(startedAt, delay) {
    const now = new Date();
    const end = new Date(startedAt.getTime() + delay);
    return Math.max(0, end.getTime() - now.getTime());
}

function RefresherTimer(props) {
    const [startedAt, setStartedAt] = useState(new Date());
    const [timeRemaining, setTimeRemaining] = useState(getTimeRemaining(startedAt, props.delay));

    useEffect(() => {

        if (timeRemaining <= 0) {
            // The component is set to idle, we do not set the interval.
            return;
        }

        // Set the interval to refresh the component every second.
        const i = setInterval(() => {
            const nowRemaining = getTimeRemaining(startedAt, props.delay);
            setTimeRemaining(nowRemaining);

            if (nowRemaining <= 0) {
                props.callback();
                clearInterval(i);
            }
        }, 1000);

        return () => {
            clearInterval(i);
        };
    });

    let message = `Refreshing in ${Math.ceil(timeRemaining / 1000)}s.`;
    if (timeRemaining <= 0) {
        message = 'Refreshing now...';
    }

    return <div>{message}</div>;
}

RefresherTimer.propTypes = {
    callback: PropTypes.func.isRequired,
    delay: PropTypes.number
};

RefresherTimer.defaultProps = {
    delay: 2000
};

export default RefresherTimer;

试图与key一起使用:

<RefresherTimer delay={20000} callback={props.updateListOfObjects} key={listOfObjects} />

尝试与道具更改一起使用:

<RefresherTimer delay={20000} callback={props.updateListOfObjects} somethingThatChanges={listOfObjects} />

listOfObjects指的是一个对象数组,对象本身不一定会改变,因此数组应该与进行比较== 。通常,该值将来自Redux,其中操作updateListFobjects会导致数组重新初始化,如下所示:NewListObjects=[…ListObjects]


共有3个答案

居飞扬
2023-03-14

使用自定义钩子

js prettyprint-override">export const useComponentDidUpdate = (effect, dependencies) => {
  const hasMounted = useRef(false);

  useEffect(
    () => {
      if (!hasMounted.current) {
        hasMounted.current = true;
        return;
      }
      effect();
    }, 
    dependencies
  );
};

初始渲染后,效果将不会运行。此后,它取决于应观察的值数组。如果为空,则将在每次渲染后运行。否则,它将在其中一个值发生更改时运行。

红弘盛
2023-03-14

简言之,当数组的引用更改时,您希望重置计时器,对吗?如果是这样,您将需要使用一些扩散机制,一个基于纯钩子的解决方案将利用useffect的第二个参数,如下所示:

function RefresherTimer(props) {
  const [startedAt, setStartedAt] = useState(new Date());
  const [timeRemaining, setTimeRemaining] = useState(getTimeRemaining(startedAt, props.delay));

  //reset part, lets just set startedAt to now
  useEffect(() => setStartedAt(new Date()),
    //important part
    [props.listOfObjects] // <= means: run this effect only if any variable
    // in that array is different from the last run
  )

  useEffect(() => {
    // everything with intervals, and the render
  })
}

有关此行为的更多信息,请参见此处https://reactjs.org/docs/hooks-effect.html#tip-通过跳过效果优化性能

罗寒
2023-03-14

useRef在函数组件中创建一个实例变量。它充当一个标志,指示它是否处于挂载或更新阶段,而不处于更新状态。

const mounted = useRef();
useEffect(() => {
  if (!mounted.current) {
    // do componentDidMount logic
    mounted.current = true;
  } else {
    // do componentDidUpdate logic
  }
});
 类似资料:
  • 从 react 导入 useState,将其粘贴到正文函数,但 react 告诉我错误的使用钩子。虽然另一个钩子像这样工作。

  • 问题内容: tldr; 如何模拟或将prop与数组配合使用以强制重置组件? 我正在实现一个显示计时器的组件,并在该组件达到零时执行回调。目的是让回调更新对象列表。后一个组件由新的React钩子 和组成。 该包含在该定时器启动时的基准,而剩余的时间。该套间隔称为每秒钟更新的剩余时间,并检查是否回调应该叫。 该组件并不是要重新安排计时器的时间,或者在间隔达到零时保持间隔不变,而是应该执行回调和空闲。为

  • 更新状态的正确方式是什么,是一个嵌套对象,在与钩子反应? 如何使用将更新为(附加字段)? (更改值)?

  • 如何使用钩子(或任何其他钩子)来复制? 在传统的类组件中,我将执行以下操作: 使用hook: (完整示例:https://codesandbox.io/s/2oo7zqzx1n) 这不起作用,因为在中返回的“cleanup”函数捕获装载期间的道具,而不是卸载期间的道具状态。 如何在不运行函数体(或清除)的情况下对每个道具更改进行清理? 一个类似的问题并没有涉及获得最新道具的部分。 文件状态为: 如

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

  • 我第一次面对的问题很小。我试图使用一个简单的useState,但出于某种原因,我不明白为什么React会给我一个错误,不管我想做什么--没有什么能修复它。 这是错误的图像:错误描述: 错误:无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一:1.React和呈现器(例如React DOM)2的版本可能不匹配。你可能违反了钩子3的规则。在同一个应用程序中可能有多个React副