繁体   English   中英

防止在React JS中多次调用方法

[英]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函数被调用了两次: whenMountdidMount

因此,功能齐全的方法将是:

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM