2017-04-06 70 views
0

我在教自己反应一个超级简单的应用程序,要求用户键入在UI中呈现的单词。如果用户输入正确,应用会显示另一个单词,依此类推。ReactJS清除来自父组件的输入

我得到它几乎工作,除了一件事:一个字输入正确后,我需要清除输入元素。我在这里关于输入元素如何明确自己看到几个答案,但我需要从包含它的组件清除它,因为这是输入被检查......

// 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的地方,但这没有任何意义,因为它是一个参数,而不是组件的状态。我是否应该将组件传递给更改函数?也许我可以改变它的状态,但这听起来像是一个糟糕的主意设计。

回答

5

这样做的两种常见方式是通过父级中的状态控制值或使用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>

+0

这是非常有帮助!非常感谢。你可以评论一个人的可取性吗?看起来像抱着孩子的状态最终会让父母感到孩子的细节膨胀,但是在参考上调用一个函数似乎不像声明那样反应想要的东西? – user1272965

+0

我认为对于使用ref来清除的简单用例很好,可能更可取。当你不需要从父母那里改变孩子的价值时,它也很好。另一方面,如果需要从父级更改值,则在父级或某个存储组件中拥有状态会更好。 (否则,为了改变孩子的价值,你还需要在孩子身上编写另一种方法)。当你需要提交表单时,它还有一个父组件可以访问所有的值来进行验证。 – noveyak

0

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

虽然@ noveyak的two solutions工作正常,但我想分享一个不同的想法,这使我能够在父母和子女之间分配责任:父母知道何时清除表单,以及知道如何对此做出反应,而不使用参考。

这个想法是使用一个修订计数器,每次按下“清除”按钮时都会增加计数器,并对儿童中此计数器的更改作出反应。

在下面的例子中,有三个相当简单的孩子对Clear按钮作出反应。

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>

编辑: 我只是偶然发现了这个美丽的简单solution with key这是精神有点类似(您可以通过父母的revision作为孩子的key