What is the best way to handle state changes in a deep node which also need to be handled by a parent node. Here is my situation:
<Table>
<Row prop={user1}>
<Column prop={user1_col1} />
<Column prop={user1_col2} />
</Row>
<Row prop={user2}>
<Column prop={user2_col1} />
<Column prop={user2_col2} />
</Row>
<TableFooter>
<FooterColumn prop={sum1} />
<FooterColumn prop={sum2} />
</TableFooter>
</Table>
Whenever someone is changing anything in the column property I only have to maintain the state of this value within that Column component. However, I now would like a sum of these values in the FooterColumn component. What is the best way to achieve this?
If I'm going to pass up the state change I must keep states in multiple places and then pass it down, this is a lot of tedious work. Is it best to use EventEmitters or am I missing something?
We can prevent this default behaviour by making a small modification to the definition of the handleSubmit function. We call a preventDefault on the event when submitting the form, and this will cancel the default event behavior (browser refresh) while allowing us to execute any code we write inside handleSubmit.
stopPropagation() within a ReactJS component to stop a click event from bubbling up and triggering a click event that was attached with JQuery in legacy code, but it seems like React's stopPropagation() only stops propagation to events also attached in React, and JQuery's stopPropagation() doesn't stop propagation to ...
Benefits of using synthetic events: Cross browsers applications are easy to implement. Synthetic events are that ReactJS reuses these events objects, by pooling them, which increase the performance.
So, all you need is to keep track of the state in the parent component, and share the state update function with the children:
var Parent = React.createClass({
getInitialState: function() {
return {
users: [
{name: 'Matt', values: [1, 2]},
{name: 'user517153', values: [4, 5]}
]
};
},
updateValue: function(rowId, colId, newValue) {
var newUsersState = this.state;
newUsersState.users[rowId].values[colId] = newValue;
this.setState({users: newUsersState});
},
render: function() {
var rows = this.state.users.map(function(user, r) {
var cols = user.values.map(function(value, c) {
return (
<Column key={c} prop={value} rowId={r} colId={c} onChange={this.updateValue}/>
);
});
return (
<Row key={r} prop={user}>
{cols}
</Row>
);
});
// Yes, it could be more efficient if you did it all in one map/forEach - doing this in a second one for clarity
var footerCols = this.state.users.map(function(user) {
var sum = 0;
user.values.forEach(function(value) { sum+= value; });
return (
<FooterColumn prop={sum} />
);
});
return (
<Table>
{rows}
<TableFooter>
{footerCols}
</TableFooter>
</Table>
);
}
});
In your Column
class, you simply need something along the lines of:
var Column = React.createClass({
onChange: function(event) {
var props = this.props;
var newValue = event.target.value; // Get the new value somehow - this is just an example
props.onChange(props.rowId, props.coldId, newValue);
},
render: function() {
var props = this.props;
return (
<td onChange={this.onChnage}>{props.prop}</td>
);
}
});
Hope that makes sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With