假设我有一个这样的元素树:
<Form>
<FormItem>
<Input></Input>
</FormItem>
<Input></Input>
<MyInput></MyInput>
</Form>
我想停用所有Input
和MyInput
组件。
我想要遍历并自动添加禁用的prop,而不是将{disabled: true}
添加到所有这些Input组件中。因此,当我删除或添加Input
组件时,我不应该关注disabled
道具。
答案 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
属性的代码段是什么?还有另外两种方法可以从我能想到的父母那里管理孩子的状态:
在refs
中存储对输入组件的引用,并在父级中管理它们(但这又涉及您要避免的其他prop
。
为渲染的组件授予特定的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将每个Input
和MyInput
组件连接到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.children
和React.Children
助手。您也许可以制作一个容器组件来递归地迭代其子组件,修改叶节点(没有子组件的叶子节点)以添加disabled
道具。
例如,请查看https://mxstbr.blog/2017/02/react-children-deepdive/#manipulating-children。