![](/img/trans.png)
[英]React.js async rendering: when componentWillMount will be called multiple times
[英]Prevent a method to be called multiple times in React JS
我试图通过在React中实现Thinking来尝试使用reactjs多字段组件,但是无法弄清楚为什么子级中的方法在这里多次调用。
var i = 0; class SearchBar extends Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange(key) { //this method is called multiple times during Render() console.log(i++); return function(e) { var value = key !== 'inStockOnly' ? e.target.value : e.target.checked; this.props.onUserInput( key, value ); }.bind(this); } render() { return ( <form> <input type="search" value={this.props.filterText} placeholder="Search ..." ref={(input) => {input.focus();}} onChange={this.handleChange('filterText')} /> <p> <input type="checkbox" checked={this.props.inStockOnly} onChange={this.handleChange('inStockOnly')} /> {' '} Only show products in stock </p> </form> ); } } class FilterableProducts extends Component { constructor(props) { super(props); this.state = { filterText: '', inStockOnly: false }; this.handleInput = this.handleInput.bind(this); } handleInput(key, value) { /*var state = {}; state[key] = value; console.log(state); this.setState(state);*/ //above is what I am trying to do later on but still stuck on why setState does not work //test this.setState({ filterText: 'foo', inStockOnly: true }); } render() { return ( <SearchBar filterText={this.state.filterText} inStockOnly={this.state.inStockOnly} onUserInput={this.handleInput} /> ); } }
//updated handleChanged handleChange(key, e) { var value = key !== 'inStockOnly' ? e.target.value : e.target.checked; this.props.onUserInput( key, value ); } //updated handleInput handleInput(key, value) { //var state = {}; //state[key] = value; //this.setState(state); //console.log(state); //above is what I am trying to do //test this.setState({ filterText: 'g', inStockOnly: true }); }
<!--i changed the event listener to this now its not called directly --> <input type="search" value={this.props.filterText} placeholder="Search ..." ref={(input) => {input.focus();}} onChange={(e)=>this.handleChange('filterText', e)} />
任何建议表示赞赏
编辑 :是的,应该立即调用它们,因为您将返回一个在onChange
时绑定到onChange
的函数。 内部函数将仅称为onChange
。 但是,您将需要传递密钥。
第二次编辑 :
handleInput(event) {
this.setState({
filterText: event.target.value,
inStockOnly: true
});
}
<input type="search" value={this.state.filterText} placeholder="Search ..." ref={(input) => {input.focus();}} onChange={this.handleInput} />
原件 :
handleChange(key) {
//this method is called multiple times during Render()
console.log(i++);
return function(key, event) {
var value = key !== 'inStockOnly' ? event.target.value : event.target.checked;
this.props.onUserInput(
key,
value
);
}.bind(this);
}
事件触发时,事件将作为最后一个参数传递。
setState
不能正常工作吗? 您在handleInput
正确使用了它。
注释掉的setState
不会起作用。 您应该只在构造函数中创建状态,并且还要注意,尽管设置状态后的console.log()
可能仍然为空,因为setState
为提高性能而异步,并且可能直到以后才更新。
var state = {};
state[key] = value;
console.log(state);
this.setState(state);*/
您将需要componentDidUpdate
并在其中执行console.log或使用setState
的回调,即this.setState({state[key]: value}, function() {console.log(this.state)});
这将始终给出正确的状态。
刚刚发现了为什么我的“ setState”“无法正常工作”。 这是由于ref
属性使用不当造成的。 通过删除ref={(input) => {input.focus();}}
,代码将起作用。 在我的情况下,我可以将其更改为ref={(input) => if(input === null) return; {input.focus();}}
ref={(input) => if(input === null) return; {input.focus();}}
将保留焦点功能。 这是因为ref
函数被调用了两次: whenMount
和didMount
因此,功能齐全的方法将是:
class SearchBar extends Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange(key, e) { var value = key !== 'inStockOnly' ? e.target.value : e.target.checked; this.props.onUserInput( key, value ); } render() { return ( <form> <input type="search" value={this.props.filterText} placeholder="Search ..." ref={(input) => {if(input === null) return;input.focus();}} onChange={(e)=>this.handleChange('filterText', e)} /> <p> <input type="checkbox" checked={this.props.inStockOnly} onChange={(e)=>this.handleChange('inStockOnly', e)} /> {' '} Only show products in stock </p> </form> ); } } class FilterableProducts extends Component { constructor(props) { super(props); this.state = { filterText: '', inStockOnly: false }; this.handleInput = this.handleInput.bind(this); } handleInput(key, value) { var state = {}; state[key] = value; this.setState(state); } render() { return ( <SearchBar filterText={this.state.filterText} inStockOnly={this.state.inStockOnly} onUserInput={this.handleInput} /> ); } }
通过使用onChange={(e)=>this.handleChange('inStockOnly', e)} />
和onChange={(e)=>this.handleChange('filterText', e)}
我们可以避免使用过多的ref
在多个字段中
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.