I have:
App
with a child component Filter
.<input onChange={handler}>
.handler
is a prop
that 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);
it is because you are rendering the form in a function inside render(). Every time your state/prop change, the function returns a new form. it caused you to lose focus.
1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.
We can use focus() function to focus the particular input field.
You're creating a new component class inside the render function.
Part of react's diffing algorithm looks at the components, and if it sees you rendered a different type component in one spot it says "the structure is probably significantly different, so I won't waste time diffing the children". It throws out the node, and renders the new result to the DOM.
Move var filter = React.createClass...
somewhere it's only executed once, and it'll work fine.
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