【问题标题】:Pass data between a container and its children components in react在反应容器及其子组件之间传递数据
【发布时间】:2020-03-11 01:00:28
【问题描述】:

我有一个 <Container /> 组件,它将 <Card /> 列表作为子项:

<Container>
  <Card />
  <Card />
</Container>

&lt;Card /&gt; 有一个布尔状态 openExpansion,一旦更改,所有兄弟&lt;Card /&gt; 将更改为相同的值。实现这一目标的最佳方法是什么? 显然我可以将openExpansion 设置为&lt;Container /&gt; 状态并将其注入每个&lt;Card /&gt;。我也不想使用 redux store,因为我不知道 &lt;Container /&gt; 会在哪里被调用。但是有没有办法让openExpansion 保持&lt;Card /&gt; 状态,同时达到同样的效果? 谢谢!

【问题讨论】:

  • 听起来您已经知道可以说是最好的解决方案是什么,将 bool 移动到父状态。但是你能告诉我们为什么你不想这样做吗?
  • @ChrisG 不,我不知道最好的解决方案,这就是讨论的重点。
  • 在您的问题中提到了最佳解决方案。再次:将 bool 移至父级,就像这里推荐的至少三个答案一样。如果您不想这样做,请告诉我们为什么不这样做。
  • @ChrisG 因为通过这种方式, 将始终依赖从 传递的 props,并且它最好称为 而不是更通用的 组件。有一个解决方案来实现通用性会很好。但也许没有办法做到这一点。
  • 如果没有某种外部包装器(父组件、上下文、redux 等),子级无法相互通信。

标签: javascript reactjs react-hooks react-props


【解决方案1】:

在我看来你必须提升你的状态:https://reactjs.org/docs/lifting-state-up.html

因此,在您的情况下,您可以创建一个方法/函数来包装这些卡片。

class WrappedCards extends React.Component {
  constructor(props) {
    super(props);
    this.handleOpenExpansion= this.handleOpenExpansion.bind(this);
    this.state = {openExpansion : false};
  }

  handleOpenExpansion(value) {
    this.setState({openExpansion : value});
  }

  render() {

    return (
      <Container>
        <Card
          handleOpenExpansion={this.handleOpenExpansion} />
      </Container>
    );
  }
}

【讨论】:

    【解决方案2】:

    我认为您解释了一个选项,即在 Container 中拥有一个变量并将其传递给每个 Card 组件。另一种选择是在 Card 组件中使用静态属性。每个 Card 实例都将具有相同的值。

    【讨论】:

      【解决方案3】:

      只需在主组件中创建一个状态,并将更新状态的函数传递给 Card。类似的东西

         const App = () => {
      
         const [openExpansion, setOpenExpansion] = React.useState(false);
      
         return (
           <Container>
           <Card setOpenExpansion={setOpenExpansion} openExpansion={openExpansion} />
            <Card />
          <Card setOpenExpansion={setOpenExpansion} openExpansion={openExpansion} /><Card /> /* Similar to above card */
           </Container>
          );
         };
      
        const Card = ({setOpenExpansion openExpansion})  => {
          return (
             <div onClick={() => openExpansion(true)}>
                  {openExpansion ? "opened" : ""}
             </div>
          );
        }
      

      如果我没看错,这就是你想通过传递 setState、状态变量来实现的目标。

      【讨论】:

        【解决方案4】:

        如果你想在兄弟姐妹之间共享相同的值,你应该在每个孩子中放置 openExpansion 道具。 此外,如果您想更改 openExpansion,您可以在 Container 中创建一个函数

        class Container extends React.Component{
            ....
            state = {
                openExpansion: true
            }
        
            changeOpenExpansionValue = (value) => this.setState({openExpansion:value})
            render(
                <div>
        
                <Card openExpansion={this.state.openExpansion} 
                    toggleOpenExpansion={this.changeOpenExpansionValue }/>
        
                <Card openExpansion={this.state.openExpansion} 
                    toggleOpenExpansion={this.changeOpenExpansionValue }/>
                </div>    
        
            )
        
        }
        

        任何时候您想更改一个子组件的所有值,只需从您的卡片中调用this.props.toggleOpenExpansion(boolValue)

        您不能在每个 Card 本地保留 openExpansion 值,因为它只能在 Card 组件内部存储和访问,并且可能与兄弟中的值不同

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-26
          • 1970-01-01
          • 1970-01-01
          • 2021-06-30
          • 2016-05-25
          • 2022-01-21
          • 2020-10-26
          • 1970-01-01
          相关资源
          最近更新 更多