所以,我有多个ReactComponent。最初,我认为有一个父组件(让我们称之为GrandPa)有自己的状态,它会将有关其状态的一些信息传递给另一个组件(称之为Parent)。同样,父母将他的一些孩子和孩子传给了GrandChild。所以我们有层次结构:
GrandPa - >父母 - >孩子 - > GrandChild
但是,我很快意识到,当我用方法this.setState(prevState => (<new state based on prevState>))
更改GrandPa的状态时,更改不会沿着通道级联。我意识到的另一个问题是在频道上传递更改。我还没有找到一个很好的方法来做到这一点。 (之前,我通过将一些事件绑定到DOM中的组件并具有可从所有ReactComponent访问的公共变量来做一些超级粗略的事情。然后当任何人触发特定事件时,我会尝试触发将更新事件的事件各个组成部分......长话短说,这造成了很多问题并且很难看。)
所以,我有下面的示例代码,我尝试只使用父和子这样做。这是一个虚拟的例子,但它只是学习如何做到这一点。名为ReactRandom
的父级有一个状态{name: <name>}
,并且有一个方法可以将该名称更改为随机字符串。当ReactRandom
呈现时,它从另一个组件ReactRandomNested
呈现该名称,该组件基本上打印出通过其自己的道具传递的名称。在这里,我在ReactRandomNested
中创建了一个方法,它明确地呈现了这些更改(我不想要这样做,我认为有一种方法可以将更新级联到通道而不必明确地执行此操作,因为它会变得非常讨厌我们有> 2个嵌套级别)。但是,即使这样也行不通。它有一步延迟,并在当前时间步长呈现先前的更新。
无论如何,这是我目前的代码:
class RandomReactNested extends React.Component {
constructor(props) {
super(props);
this.state = {name: props.name};
}
handleChange() {
let self = this;
self.setState({name: self.props.name});
}
render() {
let self = this;
return React.createElement("span", {
onClick: () => self.handleChange.call(this)
}, self.state.name);
}
}
class RandomReact extends React.Component {
constructor (props){
super(props);
this.state = {name: props.name};
this.changeName.bind(this);
}
changeName () {
let random_word_length = Math.round(Math.random()*20),
index_count = 0,
new_name = "",
alphabet = "abcdefghijklmnopqrstuvwxyz";
for (index_count; index_count <= random_word_length; index_count += 1) {
new_name += `${alphabet[Math.round(Math.random()*random_word_length)]}`;
}
console.log(new_name);
this.setState(prevState => ({
name: new_name
}));
}
render() {
let self = this;
return React.createElement("div", {
key: 2,
onClick: () => (this.changeName.call(self))
},
React.createElement(RandomReactNested, {
name: self.state.name
}));
}
}
顺便说一句,我是React的新手,我正在努力学习如何有效地使用它。我也从ReactJS网站上看到了这个页面的末尾(https://reactjs.org/docs/composition-vs-inheritance.html),它似乎反对这个建议(但我不完全确定?):
“那么继承怎么样?在Facebook上,我们在成千上万的组件中使用React,我们没有找到任何建议创建组件继承层次结构的用例。道具和组合为您提供了自定义组件外观所需的所有灵活性并且以明确和安全的方式行为。请记住,组件可以接受任意道具,包括原始值,React元素或函数。如果要在组件之间重用非UI功能,我们建议将其提取到单独的JavaScript模块中。组件可以导入它并使用该函数,对象或类,而不需要扩展它。“
咳嗽,还原,咳嗽
无论如何,路过道具是一条单行道!你可以将事情传递下去并使用它们,但是你无法传递它们。操纵父组件的唯一方法是将整个函数作为props传递。
updateGrandpaState(newData){
this.setState({ originalData: newData})
}
从爷爷组件中你可以将它传递给你......
<ParentComponent updateGrandpaState={this.updateGrandpaState} />
在您的父组件内,您可以调用
this.props.updateGrandpaState(parentComponentData)
然后,它将触发生成在grandpaComponent中的原始函数,从而更新grandpaComponent状态。
是的,你可以走得更远,预警,你越走越丑陋......
爷爷里面
< ParentComponent updateGrandpaState={this.updateGrandpaState} />
内部父母
< ChildComponent updateGrandpaState={this.props.updateGrandpaState} />
在孩子里面
this.props.updateGrandpaState(childComponentData)
当你深入两级时,我在开发工作时也会在componentDidMount上调试console.log(this.props)。
为了使事情变得更酷,你甚至可以将grandpaState传递给ParentComponent来使用,你可以连接到componentWillRecieveProps .....
<ParentComponent grandpaState={this.state} updateGrandpaState={this.updateGrandpaState} />
但老实说,一旦你学会了redux,设置了几次,它真的很棒,我永远不会用它!