【问题标题】:How to trigger useEffects before render in React?如何在 React 渲染之前触发 useEffect?
【发布时间】:2020-12-21 22:42:54
【问题描述】:

我有一个 prop 从 ParentComponent 传递到 ChildComponent,它会根据用户的输入而变化。我想在 ChildComponent 渲染之前该道具发生变化时触发 ChildComponent 中的数据获取。我该怎么做?我通过使用 useEffects(()=>{},[props.a, props.b]) 尝试了以下方式,但这总是在渲染之后调用。请帮忙!

import React, { useEffect, useState } from "react";
import "./styles.css";

export default function parentComponent() {
  const [inputs, setInputs] = useState({ a: "", b: "" });
  return (
    <>
      <input
        value={inputs.a}
        onChange={(event) => {
          const value = event.target.value;
          setInputs((prevState) => {
            return { ...prevState, a: value };
          });
        }}
      />
      <input
        value={inputs.b}
        onChange={(event) => {
          const value = event.target.value;
          setInputs((prevState) => {
            return { ...prevState, b: value };
          });
        }}
      />
      <ChildComponent a={inputs.a} b={inputs.b} />
    </>
  );
}

function ChildComponent(props) {
  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState({});

  useEffect(() => {
    console.log("updating new data based on props.a: " + props.a);
    setData({ name: "john " + props.a });
    return () => {};
  }, [props.a, props.b]);

  useEffect(() => {
    console.log("data successfully changed");
    console.log(data);
    if (Object.keys(data).length !== 0) {
      setIsLoading(false);
    }
    return () => {};
  }, [data]);

  function renderPartOfComponent() {
    console.log("rendering POC with props.a: " + props.a);
    return <div>data is: {data.name}</div>;
  }
  return (
    <div className="App">{isLoading ? null : renderPartOfComponent()}</div>
  );
}

在控制台中我得到的是:

rendering POC with props.a: fe 
rendering POC with props.a: fe 
updating new data based on props.a: fe 
rendering POC with props.a: fe 
rendering POC with props.a: fe 
data successfully changed 
Object {name: "john fe"}
rendering POC with props.a: fe 
rendering POC with props.a: fe 

如果您知道我如何使代码更高效,那也将是一个很大的帮助!

这是代码的代码框链接:https://codesandbox.io/s/determined-northcutt-6z9f8?file=/src/App.js:0-1466

【问题讨论】:

  • 你认为这个答案会有帮助吗? stackoverflow.com/a/56818036
  • @Abhilash 感谢您的回复,但在该答案中讨论的方法更多的是如何在组件安装时运行一段代码,但在我的情况下,第一次一切正常组件安装的时间,但是当 props 更改 return ( ) 块在调用 useEffect 之前呈现,这是一个问题,因为我想为新的 props 获取适当的数据

标签: javascript reactjs react-hooks frontend use-effect


【解决方案1】:

useEffect 总是在组件的渲染阶段之后调用。这是为了避免在渲染提交阶段发生任何副作用(因为它会导致组件变得高度不一致并继续尝试渲染自身)。

  • 您的 ParentComponentInput、Input 和 ChildComponent 组成。
  • 当您在文本框中键入时,ParentComponent: inputs 状态会被修改。
  • 此状态更改会导致 ChildComponent 重新渲染,因此会调用 renderPartOfComponent(因为 isLoading 在之前的渲染中仍然为 false)。
  • 重新渲染后,useEffect 将被调用(Parent 的状态传播到 Child)。
  • 由于 isLoading 的状态已从效果中修改,因此会发生另一次渲染。

【讨论】:

    【解决方案2】:

    我通过在 ChildComponent 中创建和维护状态找到了解决方案

    所以,进程的顺序是这样的: 修改道具 -> 渲染发生 -> 执行 useEffect 块。

    我通过简单地在 childComponent 中实例化一个状态并确保 props 状态与渲染之前子组件中的状态相同来找到解决方法,否则它只会显示正在加载...这非常有效。

    【讨论】:

    • 如果您愿意展示一个简单的代码演示,那就太好了
    猜你喜欢
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 2019-08-20
    • 2021-04-17
    相关资源
    最近更新 更多