如何在react元素树中更改叶节点的道具

时间:2017-06-16 07:32:19

标签: javascript reactjs react-native react-jsx

假设我有一个这样的元素树:

<Form>
  <FormItem>
     <Input></Input>
  </FormItem>
  <Input></Input>
  <MyInput></MyInput>
</Form>

我想停用所有InputMyInput组件。

我想要遍历并自动添加禁用的prop,而不是将{disabled: true}添加到所有这些Input组件中。因此,当我删除或添加Input组件时,我不应该关注disabled道具。

3 个答案:

答案 0 :(得分:1)

首先,您需要在父组件中定义一个状态,与输入组件的disabled属性相对应,让我们将其称为this.state.isInputDisabled。因此,您可以将其作为prop传递:

<Form>
  <FormItem>
     <Input isDisabled={this.state.isInputDisabled}></Input>
  </FormItem>
  <Input isDisabled={this.state.isInputDisabled}></Input>
  <MyInput isDisabled={this.state.isInputDisabled}></MyInput>
</Form>

然后,当您更改父组件中的状态时,还需要更新子组件。要覆盖componentWillReceiveProps方法,例如:

class MyInput extends React.Component {

  componentWillReceiveProps(nextProps) {
    this.forceUpdate();
  }

  render() {
    return <input type="text" disabled={this.props.isDisabled} />
  }
}

回答你的评论:

您实际期望为您处理disabled属性的代码段是什么?还有另外两种方法可以从我能想到的父母那里管理孩子的状态:

  1. refs中存储对输入组件的引用,并在父级中管理它们(但这又涉及您要避免的其他prop

  2. 为渲染的组件授予特定的HTML类,并使用vanilla JS更新disabled道具:

    function toggleInputDisabled(disable) {
      document
        .getElementsByClassName('your-input-class')
        .forEach(elem => elem.disabled = disable);
    }
    

    在React中不禁止使用vanilla JS,但这被认为是一种不好的做法,只有在看不到简单的出路时才应该使用它。

答案 1 :(得分:1)

向下传递道具是React的方式,但是如果你绝对坚持不想这样做,那么有几种选择可供选择:

使用某种状态容器,例如Redux

您可以通过Actions和Reducers集中管理Redux状态下的isInputDisabled标志。然后,通过react-redux将每个InputMyInput组件连接到Redux状态。当Redux状态发生变化时,所有通过react-redux连接到它的组件都会被通知并相应地进行渲染。

Dan Abramov(Redux的联合创始人)的这两个视频教程是一个很棒的介绍和高级指南:

使用React Context

这被认为是一个更高级的功能,React团队不鼓励这样做。它确实变得有点“神奇”,我个人不喜欢它,因为你不再具有组件所采用的道具的透明度。从上下文文档:

  

绝大多数应用程序不需要使用上下文。

     

如果您希望应用程序稳定,请不要使用上下文。它是一个   实验API,它很可能在未来的版本中破坏   反应。

     

如果您不熟悉Redux或者状态管理库   MobX,不要使用上下文。对于许多实际应用,这些   库和它们的React绑定是管理的好选择   与许多组件相关的状态。它更有可能   Redux是解决问题的正确方法,而不是上下文   正确的解决方案。

     

如果您不是经验丰富的React开发人员,请不要使用上下文。那里   通常是使用props实现功能的更好方法   和州。

     

如果您坚持使用上下文尽管有这些警告,请尝试隔离   您将上下文用于小区域并避免使用上下文API   直接在可能的情况下,以便在API时更容易升级   变化。

答案 2 :(得分:1)


提供的答案都不是OP所要寻找的,这在这里很清楚:

  

我想遍历并自动添加禁用的道具

要遍历React组件的子代,请查看this.props.childrenReact.Children助手。您也许可以制作一个容器组件来递归地迭代其子组件,修改叶节点(没有子组件的叶子节点)以添加disabled道具。

例如,请查看https://mxstbr.blog/2017/02/react-children-deepdive/#manipulating-children