首页 > 解决方案 > 如何动态构建一次反应组件,但仍然让它们访问父状态?

问题描述

我正在根据外部排序动态构建 React 子级。不幸的是,初始构建过程(如下所示.forEach)非常昂贵:

  const [amt, setAmt] = useState(0);
  const [output, setOutput] = useState();

  useEffect(() => {
    const order = ["second", "first"];

    // In reality, this is expensive logic to properly render the child components
    order.forEach((item, index, array) => {
      if (item === "first") {
        array[index] = <First key={1} amt={amt} />;
      } else {
        array[index] = <Second key={2} amt={amt} />;
      }
    });

    setOutput(order);
  }, []); // does not work unless I pass the amt state, which I don't want :(

如果我在加载时使用useEffect(()=>{expensive operation},[]);状态构建孩子,则不会传递给孩子。

如果我在每个状态更改上建立顺序,useEffect(()=>{expensive operation},[amt]);这可行,但会产生很多不必要的开销,每次amt更改时都会重建孩子的顺序。

我怎样才能动态地包含我的FirstSecond组件一次,但仍然让他们访问我传递给他们的状态变量?

这是完整的代码:

import React, { useEffect, useState } from "react";

function First({ amt }) {
  return <div id="first">{`First: ${amt}`}</div>;
}

function Second({ amt }) {
  const dbl = amt * 2;
  return <div id="second">{`Second ${dbl}`}</div>;
}

export default function Parent() {
  const [amt, setAmt] = useState(0);
  const [output, setOutput] = useState();

  useEffect(() => {
    const order = ["second", "first"];

    // In reality, this is expensive logic to properly render the child components
    order.forEach((item, index, array) => {
      if (item === "first") {
        array[index] = <First key={1} amt={amt} />;
      } else {
        array[index] = <Second key={2} amt={amt} />;
      }
    });

    setOutput(order);
  }, []); // does not work unless I pass the amt state, which I don't want :(

  useEffect(() => {
    const interval = setInterval(() => {
      setAmt(amt => amt + 1);
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  return (
    <div>
      Straight:
      <First amt={amt} />
      <Second amt={amt} />
      <br />
      Dynamic:
      {output}
    </div>
  );
}

也在这里:https ://codesandbox.io/s/nifty-rain-hhjm4?file=/src/Parent.js

简而言之:我需要构建我的孩子一次,但要确保amt每次更新时他们仍然能得到状态。

标签: reactjsdynamicstate

解决方案


推荐阅读