I have:
- A component
Appwith a child componentFilter. - The child needs to mutate state in the parent, which it is doing via an
<input onChange={handler}>. - The
handleris apropthat is set on the child by the parent.
All good so far.
However, whenever the a key is pressed on the input, it loses focus. I presume it's being destroyed and re-rendered.
If I hoist the Filter component up a level into the App and drive it off the state in that, then everything works as you'd expect, but obviously I'd like to be able to nest the components and share the state at the top level.
I guess calling setState at this higher level is causing the whole thing to get re-rendered, but I thought the diffing algorithm would be clever enough to avoid replacing the node in the Filter sub-component and thus avoid blurring the focus on the <input>.
What am I doing wrong / how can I fix this? Is there a better way to structure this?
Working JSBin here: http://jsbin.com/fexoyoqi/10/edit?html,js,output
var App = React.createClass({
getInitialState: function() {
return {
items: ["Tom", "Dick", "Harry"],
filterText: ''
};
},
setFilterText: function (event) {
this.setState({filterText: event.target.value});
},
render: function () {
var filter = React.createClass({
render: function () {
return <input value={this.props.filterText} onChange={this.props.onChange}/>;
}
});
var rows = this.state.items
.filter(function (item) {
return this.state.filterText == ''
? true
: item.toLowerCase().indexOf(
this.state.filterText.toLowerCase()) > -1;
}.bind(this))
.map(function(item) {
return <li>{item}</li>
});
return (
<div>
Filter: <filter filterText={this.state.filterText}
onChange={this.setFilterText}/>
<ul>
{rows}
</ul>
</div>
);
}
});
React.renderComponent(<App />, document.body);