Just started working with React, and it's been going relatively smooth up until this point.
I have a list, that contains X pre-defined items, which means that the list is always rendered with a given amount of rows.
This data is collected from a REST API, prior to the list rendering. The data contains variables relating to the list, as well as an array that contains each item within the list.
I chose the easy route, so I populate every ponent with a single JSON object named 'data', that contains everything necessary.
Rendering the list looks something like this:
<MyList data={data} />
Then, in the getInitialState of MyList:
dataInt: this.props.data.dataInt || 0,
dataStr: this.props.data.dataStr || '',
rows: this.props.data.rows || []
So I store my array of items (JSON) in the initial state of the list (parent), and when I choose to render the list, I first create all ponents (children) in an array, like this:
var toRender = [];
for(i = 0; i < this.state.rows.length; i++) {
toRender.push(<ItemRow data={this.state.rows[i]} />);
}
and then I render like this:
return (
<div className="item-container">
<table className="item-table">
{toRender}
</table>
</div>
);
The render-function of MyItem look something like this:
return (
<tr>
<td>{this.state.dataFromItem}</td>
</tr>
);
Now, let's say I want to modify the child data from within the parent, with some new data I just got from the API. Same structure, just the value of one field/column has changed:
i = indexOfItemToBeUpdated;
var newRows = this.state.rows;
newRows[i] = data; // New JSON object with same keys, different values.
this.setState({ rows: newRows }); // Doesn't trigger re-render
this.forceUpdate(); // Doesn't trigger re-render
What am I doing wrong?
At first I thought it was because I was wrapping the render function of MyItem in a , but since it renders perfectly fine on the initial render, I will assume that is an acceptable wrapper.
After some testing, it seems that the parent view is re-rendered, but not the children (which are based on the data that is updated within the parent).
JSfiddle: /
Just started working with React, and it's been going relatively smooth up until this point.
I have a list, that contains X pre-defined items, which means that the list is always rendered with a given amount of rows.
This data is collected from a REST API, prior to the list rendering. The data contains variables relating to the list, as well as an array that contains each item within the list.
I chose the easy route, so I populate every ponent with a single JSON object named 'data', that contains everything necessary.
Rendering the list looks something like this:
<MyList data={data} />
Then, in the getInitialState of MyList:
dataInt: this.props.data.dataInt || 0,
dataStr: this.props.data.dataStr || '',
rows: this.props.data.rows || []
So I store my array of items (JSON) in the initial state of the list (parent), and when I choose to render the list, I first create all ponents (children) in an array, like this:
var toRender = [];
for(i = 0; i < this.state.rows.length; i++) {
toRender.push(<ItemRow data={this.state.rows[i]} />);
}
and then I render like this:
return (
<div className="item-container">
<table className="item-table">
{toRender}
</table>
</div>
);
The render-function of MyItem look something like this:
return (
<tr>
<td>{this.state.dataFromItem}</td>
</tr>
);
Now, let's say I want to modify the child data from within the parent, with some new data I just got from the API. Same structure, just the value of one field/column has changed:
i = indexOfItemToBeUpdated;
var newRows = this.state.rows;
newRows[i] = data; // New JSON object with same keys, different values.
this.setState({ rows: newRows }); // Doesn't trigger re-render
this.forceUpdate(); // Doesn't trigger re-render
What am I doing wrong?
At first I thought it was because I was wrapping the render function of MyItem in a , but since it renders perfectly fine on the initial render, I will assume that is an acceptable wrapper.
After some testing, it seems that the parent view is re-rendered, but not the children (which are based on the data that is updated within the parent).
JSfiddle: https://jsfiddle/zfenub6f/1/
Share Improve this question edited Apr 5, 2015 at 20:33 Joel asked Apr 5, 2015 at 16:28 JoelJoel 711 gold badge1 silver badge5 bronze badges 3- Could you put this in a jsfiddle or equivalent as it's not clear what the actual structure you have is or how the pieces interact as you've only included a few snippets of code. – WiredPrairie Commented Apr 5, 2015 at 18:15
- I've made a few changes since I posted, but the same problem still remains: jsfiddle/zfenub6f/1 – Joel Commented Apr 5, 2015 at 20:31
- Can you minimize it to just be the specific issue and make it actually function though? There's a lot of code there, and it doesn't work on jsfiddle. You may need to just add a 'key' to each row. facebook.github.io/react/docs/… – WiredPrairie Commented Apr 5, 2015 at 20:58
2 Answers
Reset to default 2I think the problem could be the your are only using getInitialState
for the Row
. You are setting state with the passed in props. If the children get new props, getInitialState
won't get called again. I always refer back to https://facebook.github.io/react/docs/ponent-specs.html to see all the lifecyle events. Try using ponentWillReceiveProps(object nextProps)
to set the state again. If you don't actually need state
in the child, remove the use of state and just use props
and it probably will work.
If you're children are using State and state is not updating, what about props? does that render just fine? If the parent changes the state of the children and the children don't reflect that change those child ponents most likely need a unique key assigned to them which tells React that these items need to be updated when the state is updated on the parent. I ran into a similar issue where props inside the child updated to reflect the parent but the state of the child would not update. Once I added keys, the solution was resolved. For further reading on this check out this blog that initially hinted the problem to me.
http://blog.arkency./2014/10/react-dot-js-and-dynamic-children-why-the-keys-are-important/
There is also the official documentation from React that explains this situation.
http://facebook.github.io/react/docs/multiple-ponents.html#dynamic-children