简体   繁体   English

ReactJS 清除来自父组件的输入

[英]ReactJS clearing an input from parent component

I'm teaching myself react with a super simple app that asks the user to type a word presented in the UI.我正在教自己用一个超级简单的应用程序做出反应,该应用程序要求用户输入 UI 中显示的单词。 If user enters it correctly, the app shows another word, and so on.如果用户输入正确,应用程序会显示另一个单词,依此类推。

I've got it almost working, except for one thing: after a word is entered correctly, I need to clear the input element.我几乎可以正常工作,除了一件事:正确输入单词后,我需要清除输入元素。 I've seen several answers here about how an input element can clear itself, but I need to clear it from the component that contains it, because that's where the input is checked...我在这里看到了几个关于输入元素如何清除自身的答案,但我需要从包含它的组件中清除它,因为那是检查输入的地方......

// 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>
      );
    }
}

See where it says alert('yes') ?看看它在哪里说alert('yes') That's where I think I should clear the value , but that doesn't make any sense because it's a parameter, not really the state of the component.这就是我认为我应该清除value ,但这没有任何意义,因为它是一个参数,而不是组件的真正状态。 Should I have the component pass itself to the change function?我应该让组件将自身传递给更改函数吗? Maybe then I could alter it's state, but that sounds like a bad idea design-wise.也许那时我可以改变它的状态,但这在设计方面听起来是个坏主意。

The 2 common ways of doing this is controlling the value through state in the parent or using a ref to clear the value.执行此操作的两种常见方法是通过父级中的状态控制值或使用 ref 清除值。 Added examples of both添加了两者的示例

The first one is using a ref and putting a function in the child component to clear The second one is using state of the parent component and a controlled input field to clear it第一个是使用 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>

I had a similar issue: I wanted to clear a form which contained multiple fields.我有一个类似的问题:我想清除包含多个字段的表单。

While the two solutions by @noveyak are working fine, I want to share a different idea, which gives me the ability to partition the responsibility between parent and child: parent knows when to clear the form, and the items know how to react to that, without using refs.虽然@noveyak 的两个解决方案运行良好,但我想分享一个不同的想法,这使我能够在父子之间划分责任:父知道何时清除表单,项目知道如何对此做出反应, 不使用引用。

The idea is to use a revision counter which gets incremented each time Clear is pressed and to react to changes of this counter in children.这个想法是使用一个修订计数器,每次按下 Clear 时都会递增,并对子项中此计数器的变化做出反应。

In the example below there are three quite simple children reacting to the Clear button.在下面的例子中,有三个非常简单的孩子对清除按钮做出反应。

 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);
 <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>

EDIT: I've just stumbled upon this beautifully simple solution with key which is somewhat similar in spirit (you can pass parents's revision as child's key )编辑:我刚刚偶然发现了这个带有密钥的漂亮简单的解决方案,它在精神上有些相似(您可以将父母的revision作为孩子的key传递)

Very very very simple solution to clear form is add unique key in div under which you want to render form from your child component key={new Date().getTime()} :清除表单的非常非常简单的解决方案是在 div 中添加唯一key ,您希望在该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>
        )
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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