首页 > web前端 > js教程 > 带钩子的 React 中不存在生命周期

带钩子的 React 中不存在生命周期

DDD
发布: 2024-11-14 15:18:02
原创
895 人浏览过

Lifecycle doesn

很久很久以前,我们在类中使用了 React,还记得吗?

当时,我们有了生命周期方法的概念,即接受在特定时刻执行的回调的类上的方法。三巨头:装载时、更新时和卸载时。

古老但黄金的课程

这很重要,在类组件上,返回的 JSX 是在 render 方法上生成的,状态附加到组件的 this 上,并且应用程序开发人员需要一种方法来知道在某些时刻执行操作。我们对组件生命周期的时间有了概念:

  • componentDidMount 是组件首次渲染并向 DOM 添加元素的时刻,也是开始连接和 API 请求等副作用的时刻。
  • shouldComponentUpdate 允许您手动设置逻辑来比较下一个 props 和状态,并返回一个布尔值来定义是否可以跳过重新渲染。
  • componentDidUpdate 是状态或 props 更改的时刻,再次调用 render 方法并对身份差异进行协调更改并应用于 DOM,有助于将状态与新 props 同步并执行逻辑操作。
  • componentWillUnmount 是 React 将从 DOM 中删除元素的时候,是清理内容和避免内存泄漏的好地方。

当然,您有一个重要的 API,例如forceUpdate,如果您使用的外部数据无法与 React 状态更新连接,它允许您手动触发重新渲染

在概念层面上,我们有一种更直接的方式来执行应用程序的流程。生命周期方法遵循 DOM 元素的类似生命周期,您可以自己执行 memo 和 forceUpdates,同步状态是执行逻辑的默认方式。

这种直接性被认为是简单的,与反应式模型相比,学习这些概念更容易。但后来,Hooks 出现并改变了一切。

未命名的反应性

过渡令人困惑。首先,为了让开发变得简单,并在某种程度上维护开发人员所拥有的 React 模型的概念愿景,许多交流试图展示 hooks 模型的相似之处。为了拥有 3 个主要的生命周期方法,他们展示了 useEffect 的解决方法。

// componentDidMount
 useEffect(() => {
    // code...

    // componentWillUnmount:
    return function cleanup() {
      // code...
    };
  }, []);

// componentDidUpdate
 useEffect(() => {
    // code...

  }, [dependencyState, dependencyProp]);
登录后复制
登录后复制

所以,大多数用 hooks 编写的新 React 代码都遵循这个想法,开始同步状态是一个自然的过程。为了保持生命周期方法的相同理念,这是调用 setState 并触发重新渲染过程的地方。

有什么问题吗?

同步状态成为问题,useEffect 的错误使用成为问题,双重重新渲染成为问题,太多重新渲染成为问题,性能成为问题。

React 的这一步有点令人困惑,至少对我来说是这样。因为,转向钩子就是转向反应式模型,即使它是一个粗粒度的模型。但传达的信息是,没有什么大的变化。没有关于反应性概念和理论的内容,即使使用 React 多年,我也只是阅读 Ryan Carniato 关于反应性和固体的博客文章才开始真正理解反应性。

即使知道 useEffect 有一个误用,我真的不明白为什么,而且缺乏关于反应性的概念理论使得钩子很容易犯错误。 useEffect 成为最令人讨厌的 hook,被一些人称为“useFootgun”。关键是,React 中存在概念上的混乱,表现为我们今天看到的 useEffect 的所有问题。

useEffect问题不是问题的原因,而是问题的结果。

钩子的生命周期怎么样

所以,这就是事情。反应性的概念中没有生命周期。

你发生了变化,你对它做出反应,产生副作用。效果是结果,而不是原因。没有状态同步,也没有挂载和卸载的概念。

无论是卸载前的第一个、第十个还是最后一个渲染都没有关系,而且钩子不关心它,顺便说一句,甚至 useEffect。

尝试一下:

// componentDidMount
 useEffect(() => {
    // code...

    // componentWillUnmount:
    return function cleanup() {
      // code...
    };
  }, []);

// componentDidUpdate
 useEffect(() => {
    // code...

  }, [dependencyState, dependencyProp]);
登录后复制
登录后复制

您将在控制台上看到每次状态更新时都会执行这两个函数。首先是清理,然后是效果回调。如果您使用带有某些状态或属性的 useEffect 来进行订阅,则每次依赖项发生更改时,都会调用清理函数,然后调用新的回调,再次进行订阅,但使用新值。

您应该将应用程序代码视为简化的 React 模型:

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

  useEffect(() => {
    console.log('effect', count);

    return () => {
      console.log('clean up', count);
    }
  }, [count]);

  return (
    <button onClick={() => setCount((state) => state + 1)}>
      {count}
    </button>
  )
}
登录后复制

如果您有这样的组件:

UI = fn(state)
登录后复制

当您单击按钮并将计数加 1 时,您真正拥有的概念上是这样的:

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

  return (
    <button onClick={() => setCount((state) => state + 1)}>
      {count}
    </button>
  )
}
登录后复制

每次点击都会再次调用 fn,并使用新的状态,生成新版本的 UI。状态应该通过用户的操作或通过异步派生生成的异步值来更改。

这样你就可以保持干净的想法:

  • 状态转换进行新的 fn 调用
  • 在新状态下,您将获得 UI 描述
  • 如果不同,请更新屏幕。

一个干净且一致的模型。

渲染器需要关心在屏幕上添加、更新和删除元素。在组件级别,重要的是:

  • 如果状态改变
  • 应用程序是否可以处理用户操作
  • JSX 中返回的结构。

Hooks 及其响应式模型使 React 与浏览器解耦,使应用程序代码不必关心您处于屏幕渲染过程的哪个时刻。您不再强制更新,甚至不再按照自己的规则处理备忘录,这对于应用开发人员来说不太直接,但在模型方面更直接。

每次重新渲染都会生成一个结构,React 负责剩下的事情。

以上是带钩子的 React 中不存在生命周期的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板