【问题标题】:React Children component lost status redering inner another componentReact Children 组件在另一个组件内丢失了状态渲染
【发布时间】:2020-10-21 06:39:19
【问题描述】:

传递给另一个组件的子组件的状态正在失去价值

[环境]:

我有 5 个组件: 默认, 包装, 子组件, 分区 1, 分区2

在默认情况下,我正在渲染 Wrapper,在 Wrapper 内部,我正在渲染 ChildrenComponent,所有这些都在默认情况下,我将传递给 Wrapper 一个名为“isDiv1”的“道具”,这也是我在默认情况下的状态,我正在通过 Default 中的按钮更改其值。

在 Wrapper 中,我正在执行逻辑分析“props.isDiv1”中的值是否为真,如果是 Div1 组件,如果不是,我保留 Div2 组件,并使用此逻辑的结果涉及“ props.children”在 Div1 或 Div2 中。

在 ChildrenComponent 我有一个存储初始文本的状态和一个输入,每次更改时,它都会将此初始文本更改为已更改的内容。

在 Div1 和 Div2 中,我有一个带有不同“className”属性的简单 div。

import React from "react";

const Div1 = props => <div className="iam-div-1">{props.children}</div>;

const Div2 = props => <div className="iam-div-2">{props.children}</div>;

const Wrapper = props => {
  const Div = props.isDiv1 ? Div1 : Div2;

  return <Div>{props.children}</Div>;
};

const ChildrenComponent = props => {
  const [text, setText] = React.useState("initial");
  return <input value={text} onChange={e => setText(e.target.value)} />;
};

export default props => {
  const [isDiv1, setIsDiv1] = React.useState(false);

  return (
    <>
      <Wrapper isDiv1={isDiv1}>
        <ChildrenComponent />
      </Wrapper>
      <button onClick={() => setIsDiv1(!isDiv1)}>change div</button>
    </>
  );
};

[问题]:

问题是每次更改ChildrenComponent的状态并点击Default中的按钮时,ChildrenComponent状态中的值都会被重置。

下面是你自己测试的链接:

https://codesandbox.io/s/headless-monad-ymc2i?file=/src/App.js

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    问题是每次isDiv1 的值发生变化时,您的Wrapper 组件都会安装一个新的Div 组件。通过挂载一个新的Div 组件,你又挂载了一个新的ChildComponent,它将始终具有初始值。

    如果组件的父组件被卸载,组件将不会保持安装状态,该组件的道具(即React.Children)也不会被保留。如果你把组件树想象成一棵真正的树;当连接到树干的树枝被切断时,树枝不会悬在半空中。

    如果您想在卸载组件时保留状态,则需要将该状态移动到组件树的更高级别。在您的情况下,它可能看起来像这样:

    const ChildrenComponent = props => {
      return <input value={props.text} onChange={e => props.setText(e.target.value)} />;
    };
    
    export default props => {
      const [isDiv1, setIsDiv1] = React.useState(false);
      const [text, setText] = React.useState("initial");
    
      return (
        <>
          <Wrapper isDiv1={isDiv1}>
            <ChildrenComponent text={text} setText={setText}/>
          </Wrapper>
          <button onClick={() => setIsDiv1(!isDiv1)}>change div</button>
        </>
      );
    };
    

    【讨论】:

    • 谢谢,我已经考虑过这个解决方案,但我不确定这是否是正确的方法
    猜你喜欢
    • 1970-01-01
    • 2021-06-08
    • 2019-11-19
    • 1970-01-01
    • 2019-10-14
    • 1970-01-01
    • 2018-01-26
    • 2020-05-27
    • 2021-02-16
    相关资源
    最近更新 更多