admin管理员组文章数量:1313808
So, I have multiple ReactComponent. Initially, I was thinking that there will be sort of a parent ponent (let's call this GrandPa) with its own state, and it will pass down some info about its state to another ponent (call it Parent). Similarly, Parent passes some of his to Child and child to GrandChild. So we have the hierarchy:
GrandPa -> Parent -> Child -> GrandChild
However, I quickly realized that when I change the state of GrandPa with method this.setState(prevState => (<new state based on prevState>))
, the changes do not cascade down the channel. Another problem I realized is passing changes up the channel as well. I have not found a nice way to do this. (Before, I did something super sketchy by binding some events to a ponent in the DOM and having a public variable that is accessible from all of the ReactComponent. Then when anyone triggers a specific event, I would try to trigger events that would update the respective ponents... Long story short, this created a lot of problems and was ugly.)
So, I have the example code below where I tried to do this with just a parent and child. It's a dummy example, but it's just to learn how to do this. The parent, called ReactRandom
has a state {name: <name>}
and has a method that changes that name to a random string. When ReactRandom
renders, it renders that name from another ponent ReactRandomNested
which basically prints out the name passed via its own props. Here, I created a method inside of ReactRandomNested
which explicitly renders the changes (which I DO NOT WANT BTW, I am thinking there is a way to cascade the updates down the channel without having to explicitly do that because it'd get nasty quicky as we have >2 nested levels). However, even this does not work. It has a 1 step delay and renders the previous update at the current timestep.
Anyway, here's the code I currently have:
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
}));
}
}
By the way, I am quite new to React and am trying to learn how to use this effectively. I also saw this from the ReactJS website toward the end of the page (.html), which seems to advice against this (but I am not entirely sure?):
"So What About Inheritance? At Facebook, we use React in thousands of ponents, and we haven’t found any use cases where we would remend creating ponent inheritance hierarchies. Props and position give you all the flexibility you need to customize a ponent’s look and behavior in an explicit and safe way. Remember that ponents may accept arbitrary props, including primitive values, React elements, or functions. If you want to reuse non-UI functionality between ponents, we suggest extracting it into a separate JavaScript module. The ponents may import it and use that function, object, or a class, without extending it."
So, I have multiple ReactComponent. Initially, I was thinking that there will be sort of a parent ponent (let's call this GrandPa) with its own state, and it will pass down some info about its state to another ponent (call it Parent). Similarly, Parent passes some of his to Child and child to GrandChild. So we have the hierarchy:
GrandPa -> Parent -> Child -> GrandChild
However, I quickly realized that when I change the state of GrandPa with method this.setState(prevState => (<new state based on prevState>))
, the changes do not cascade down the channel. Another problem I realized is passing changes up the channel as well. I have not found a nice way to do this. (Before, I did something super sketchy by binding some events to a ponent in the DOM and having a public variable that is accessible from all of the ReactComponent. Then when anyone triggers a specific event, I would try to trigger events that would update the respective ponents... Long story short, this created a lot of problems and was ugly.)
So, I have the example code below where I tried to do this with just a parent and child. It's a dummy example, but it's just to learn how to do this. The parent, called ReactRandom
has a state {name: <name>}
and has a method that changes that name to a random string. When ReactRandom
renders, it renders that name from another ponent ReactRandomNested
which basically prints out the name passed via its own props. Here, I created a method inside of ReactRandomNested
which explicitly renders the changes (which I DO NOT WANT BTW, I am thinking there is a way to cascade the updates down the channel without having to explicitly do that because it'd get nasty quicky as we have >2 nested levels). However, even this does not work. It has a 1 step delay and renders the previous update at the current timestep.
Anyway, here's the code I currently have:
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
}));
}
}
By the way, I am quite new to React and am trying to learn how to use this effectively. I also saw this from the ReactJS website toward the end of the page (https://reactjs/docs/position-vs-inheritance.html), which seems to advice against this (but I am not entirely sure?):
"So What About Inheritance? At Facebook, we use React in thousands of ponents, and we haven’t found any use cases where we would remend creating ponent inheritance hierarchies. Props and position give you all the flexibility you need to customize a ponent’s look and behavior in an explicit and safe way. Remember that ponents may accept arbitrary props, including primitive values, React elements, or functions. If you want to reuse non-UI functionality between ponents, we suggest extracting it into a separate JavaScript module. The ponents may import it and use that function, object, or a class, without extending it."
Share Improve this question asked Dec 17, 2017 at 18:34 Robert VunabandiRobert Vunabandi 1472 silver badges12 bronze badges 1- 1 Here's an answer to this that I found. x) stackoverflow./questions/46727804/… – Robert Vunabandi Commented Dec 17, 2017 at 18:40
1 Answer
Reset to default 7cough, redux, cough
Anyway, passing props is a one way street! You can pass things down, and use them, but you can't pass them up. The only way to manipulate a parent ponent is through passing an entire function as props.
updateGrandpaState(newData){
this.setState({ originalData: newData})
}
From your grandpa ponent you you would pass it down like this...
<ParentComponent updateGrandpaState={this.updateGrandpaState} />
And inside your parent ponent you can call
this.props.updateGrandpaState(parentComponentData)
Which will then fire the original function that lives in grandpaComponent, thus updating grandpaComponent State.
And yes, you can go further, forewarning, the deeper you go the uglier it gets...
Inside Grandpa
< ParentComponent updateGrandpaState={this.updateGrandpaState} />
Inside Parent
< ChildComponent updateGrandpaState={this.props.updateGrandpaState} />
Inside Child
this.props.updateGrandpaState(childComponentData)
When you go two levels deep I also console.log(this.props) on ponentDidMount while doing dev work.
To make things even cooler, you could even pass grandpaState down into ParentComponent to use, which you could hook up to ponentWillRecieveProps.....
<ParentComponent grandpaState={this.state} updateGrandpaState={this.updateGrandpaState} />
But honestly, once you learn redux, set it up a few times, it's really awesome and I would never not use it!
本文标签: javascriptDealing with Nested React Components39 State ChangesStack Overflow
版权声明:本文标题:javascript - Dealing with Nested React Components' State Changes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741924930a2405224.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论