React应用程序从根本上来说是一棵组件树,可以相互通信数据。在组件之间传递数据通常是无痛的。但是,随着应用程序树的增长,在保持可读代码库的同时传递数据变得更加困难。
假设我们有以下树结构:
这里有一个简单的树,有3个层次。在该树中,节点D和节点E都操纵一些类似的数据:假设用户输入节点D中的一些文本,我们希望在节点E中显示该文本。
我们如何将数据从节点D传递到节点E?
本文介绍了三种解决此问题的可行方法:
- Prop钻取
- Redux
- React’s context API
本文的目的是比较这些方法,并表明,当解决一个常见问题时,例如我们刚才所说的问题,可以坚持使用React的context API。
方法1: Prop钻取
这样做的方法是天真的通过props将数据从子节点传递到父节点,再将数据从父节点传递到子节点,如:D->B->A 然后 A->C->E。
这里的想法是使用onUserInput
从子节点到父节点触发的函数将输入数据从节点D传送到节点A的state
状态,然后我们将该数据从节点A的state
状态传递到节点E.
我们从节点D开始:
class NodeD extends Component {
render() {
return (
<div className="Child element">
<center> D </center>
<textarea
type="text"
value={this.props.inputValue}
onChange={e => this.props.onUserInput(e.target.value)}
/>
</div>
);
}
}
当用户键入内容时,onChange
监听函数将从prop
的onUserInput
触发该函数并传入用户输入。节点D prop中的该函数将触发节点B prop
中onUserInput
另一个函数,如下:
class NodeB extends Component {
render() {
return (
<div className="Tree element">
<center> B</center>
<NodeD onUserInput={inputValue => this.props.onUserInput(inputValue)} />
</div>
);
}
}
最后,当到达根节点A时,onUserInput
在节点B prop中触发将把节点A中的状态改变为用户输入的值。
class NodeA extends Component {
state = {
inputValue: ""
};
render() {
return (
<div className="Root element">
<center> A </center>
<NodeB
onUserInput={inputValue => this.setState({ inputValue: inputValue })}
/>
<NodeC inputValue={this.state.inputValue} />
</div>
);
}
}
inputValue
值将通过props从节点C传