ReactJS清除父组件的输入

时间:2017-04-06 22:10:05

标签: javascript reactjs

我正在教自己对一个超级简单的应用程序作出反应,该应用程序要求用户键入UI中显示的单词。如果用户正确输入,应用程序会显示另一个单词,依此类推。

我几乎可以使用它,除了一件事:正确输入一个单词后,我需要清除输入元素。我在这里看到了几个关于输入元素如何清除自身的答案,但是我需要从包含它的组件中清除它,因为那是检查输入的位置......

// the app
class AppComponent extends React.Component {
    constructor() {
      super();
      this.state = {
        words: ['alpha', 'bravo', 'charlie'],
        index: 0
      };
    }
    renderWordsource() {
      const word = this.state.words[this.state.index];
      return <WordsourceComponent value={ word } />;
    }
    renderWordinput() {
      return <WordinputComponent id={1} onChange={ this.onChange.bind(this) }/>;
    }
    onChange(id, value) {
        const word = this.state.words[this.state.index];
        if (word == value) {
            alert('yes');
            var nextIndex = (this.state.index == this.state.words.count-1)? 0 : this.state.index+1;
            this.setState({ words:this.state.words, index:nextIndex });
        }
    }
    render() {
      return (
        <div className="index">
          <div>{this.renderWordsource()}</div>
          <div>{this.renderWordinput()}</div>
        </div>
      );
    }
}

// the input component
class WordinputComponent extends React.Component {
    constructor(props) {
        this.state = { text:''}
    }
    handleChange(event) {
      var text = event.target.value;
      this.props.onChange(this.props.id, text);
    }
    render() {
      return (
        <div className="wordinput-component">
          <input type="text" onChange={this.handleChange.bind(this)} />
        </div>
      );
    }
}

查看alert('yes')的位置?这就是我认为我应该清除value的地方,但这没有任何意义,因为它是一个参数,而不是组件的状态。我应该将组件传递给更改功能吗?也许那时我可以改变它的状态,但这听起来像设计明智的坏主意。

3 个答案:

答案 0 :(得分:6)

执行此操作的两种常用方法是通过父级中的状态控制值或使用ref清除值。

增加了两个例子

第一个是使用ref并在子组件中放置一个函数来清除 第二个是使用父组件的状态和受控输入字段来清除它

class ParentComponent1 extends React.Component {
  state = {
    input2Value: ''
  }
  clearInput1() {
    this.input1.clear();
  }
  clearInput2() {
    this.setState({
      input2Value: ''
    });
  }
  handleInput2Change(evt) {
    this.setState({
      input2Value: evt.target.value
    });
  }
  render() {
    return (
      <div>
        <ChildComponent1 ref={input1 => this.input1 = input1}/>
        <button onClick={this.clearInput1.bind(this)}>Clear</button>
        <ChildComponent2 value={this.state.input2Value} onChange={this.handleInput2Change.bind(this)}/>
        <button onClick={this.clearInput2.bind(this)}>Clear</button>
      </div>
    );
  }
}

class ChildComponent1 extends React.Component {
  clear() {
    this.input.value = '';
  }
  render() {
    return (
      <input ref={input => this.input = input} />
    );
  }
}

class ChildComponent2 extends React.Component {
  render() {
    return (
      <input value={this.props.value} onChange={this.props.onChange} />
    );
  }
}

ReactDOM.render(<ParentComponent1 />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

答案 1 :(得分:1)

我有一个类似的问题:我想清除一个包含多个字段的表单。

虽然@noveyak的two solutions工作正常,但我想分享一个不同的想法,这使我能够在父母和孩子之间划分责任:父母知道何时清除表格和项目知道如何对此作出反应,而不使用refs。

这个想法是使用一个修订计数器,每次按下Clear时它会增加,并对儿童中这个计数器的变化作出反应。

在下面的示例中,有三个非常简单的孩子对“清除”按钮作出反应。

&#13;
&#13;
class ParentComponent extends React.Component {
  state = {revision: 0}
  clearInput = () => {
    this.setState((prev) => ({revision: prev.revision+1}))
  }
  render() {
    return (
      <div>
        <ChildComponent revision={this.state.revision}/>
        <ChildComponent revision={this.state.revision}/>
        <ChildComponent revision={this.state.revision}/>
        <button onClick={this.clearInput.bind(this)}>Clear</button>        
      </div>
    );
  }
}
class ChildComponent extends React.Component {
  state = {value: ''}
  componentWillReceiveProps(nextProps){
    if(this.props.revision != nextProps.revision){
      this.setState({value : ''});
    }
  }
  saveValue = (event) => {
    this.setState({value: event.target.value})
  }
  render() {
    return (
      <input value={this.state.value} onChange={this.saveValue} />
    );
  }
}
ReactDOM.render(<ParentComponent />, document.body);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
&#13;
&#13;
&#13;

修改 我偶然发现了这个非常简单的solution with key,它在精神上有些相似(你可以通过父母的revision作为孩子的key

答案 2 :(得分:0)

清除表单的非常非常简单的解决方案是在div中添加唯一的key,您要在其下从子组件key={new Date().getTime()}呈现表单:

render(){

        return(
            <div className="form_first_step fields_black" key={new Date().getTime()}>
                <Form
                className="first_step">
                
                  // form fields coming from child component
                  <AddressInfo />
                
                
                </div>
              </Form>
          </div>
        )
    }