2016-12-24 4 views
3

単純なToDoアプリケーションを作成しましたが、App(InputForm)の子コンポーネントの入力値にアクセスする際に問題があります。React.js子コンポーネントの入力値にアクセスする方法

多分私はそれが動作するように構造やロジックを再構築する必要がありますか?

はここに私のアプリケーションコンポーネントです:助けを

class InputForm extends React.Component { 
    render(){ 
    return (
     <form onSubmit={this.props.onSubmit}> 
     <input 
      ref="todoInput" 
      type="text" 
      placeholder="Type your text here" /> 
     <button type="submit">Add to list</button> 
     </form> 
    ) 
    } 
} 

ありがとう:

class App extends React.Component { 
    constructor(){ 
     super(); 
     this.state = { 
      items : [] 
     } 
    } 

    addTodo (e){ 
    e.preventDefault(); 

    let itemHeading = this.refs.todoInput.value; // TODO Access to input value 
    let itemKey = Date.now(); 

    const items = this.state.items.slice(); 

    items.push({ 
     heading: itemHeading, 
     key: itemKey 
    }) 

    this.setState({items: items}); 
    } 
    render() { 
    return (
     <div className="app-container"> 
     <InputForm onSubmit={this.addTodo.bind(this)}></InputForm> 
     <TodoItems entries={this.state.items} /> 
     </div> 
    ); 
    } 
} 

ここに私のInputFormではコンポーネントです。

+0

どのコンポーネントのコンポーネントに値を渡したいですか? – Codesingh

+0

@Codesingh 'InputForm'からの入力値を渡し、' App'コンポーネントの 'addTodo'関数でそれを使用したいと思います。私はそれが必要な行にTODOのコメントを見ることができます。 –

答えて

5

controlled componentinputを変換し、そしていつでも入力の変化にテキストの状態を更新します。 submitをクリックすると、その値をハンドラに送信します。

refsはDOMに直接アクセスする必要があるため使用しないでください。

典型的には小道具は、その親 コンポーネントが子どもとの対話唯一の方法である、データフローに反応:これはおよそrefsが言っているドキュメントを反応させるものです。子を変更するには、 を新しい小道具で再レンダリングします。ただし、いくつかのケースがあります。 は、典型的なデータフローの外部で子供を強制的に変更する必要があります。 修正する子は、Reactコンポーネントのインスタンスであるか、 DOMエレメントである可能性があります。これらの両方の場合、Reactは エスケープハッチを提供します。

これは、このエスケープハッチを必要としないケースで、プロップだけを使用する必要があります。

コメント(テストしますが、動作するはずではない)とのコード:私はあなたの子コンポーネントに親コンポーネントから親オブジェクトを渡すから直接親コンポーネントのメソッドにアクセスすることで、最も簡単な解決策を提供します

class App extends React.Component { 
    constructor(){ 
     super(); 
     this.state = { 
      items : [] 
     }; 

     // bind addTodo once in constructor 
     this.addTodo = this.addTodo.bind(this); 
    } 

    // addTodo will receive the needed value without refs 
    addTodo (heading){ 

    // concat returns a new array 
    const items = this.state.items.concat({ 
     heading, 
     key: Date.now() 
    }); 

    this.setState({ items }); 
    } 
    render() { 
    return (
     <div className="app-container"> 
     <InputForm onSubmit={this.addTodo}></InputForm> 
     <TodoItems entries={this.state.items} /> 
     </div> 
    ); 
    } 
} 

class InputForm extends React.Component { 
    constructor(props) { 
    super(props); 

    // bind onSubmit and onInput 
    this.onSubmit = this.onSubmit.bind(this); 
    this.onInput = this.onInput.bind(this); 

    // init state 
    this.state = { 
     input: '' 
    }; 
    } 

    // input change handler 
    onInput(e) { 
    this.setState({ 
     input: e.target.value 
    }); 
    } 

    // submit handler 
    onSubmit() { 
    this.props.onSubmit(this.state.input); 
    } 

    render(){ 
    return (
     <form onSubmit={this.onSubmit}> 
     <input 
      // use value and onChange so it will be a controlled component 
      value={ this.state.value } 
      onChange={ this.onInput } 
      type="text" 
      placeholder="Type your text here" /> 
     <button type="submit">Add to list</button> 
     </form> 
    ) 
    } 
} 
1

アクセスしようとしているrefsオブジェクトがInputFormインスタンスにあるため、Appからそのインスタンスにアクセスする場合は、InputFormにも参照を追加する必要があります。 それからthis.refs.InputForm.refs.todoInputでアクセスできます。

言い換えれば、ref文字列はReactから削除される予定であるため、ref文字列ではなくrefコールバックを行うのが最善です。 また、参照を過度に使用しないことをお勧めします。たぶんあなたはonChangeというイベントで親の状態の値を保持することができます。

https://facebook.github.io/react/docs/refs-and-the-dom.html#the-ref-callback-attribute

1

子コンポーネント:

class App extends React.Component { 
    constructor(){ 
     super(); 
     this.state = { 
      items : [] 
     } 
    } 

    addTodo (value){ 

    let itemHeading = value; 
    let itemKey = Date.now(); 

    const items = this.state.items.slice(); 

    items.push({ 
     heading: itemHeading, 
     key: itemKey 
    }) 

    this.setState({items: items}); 
    } 
    render() { 
    return (
     <div className="app-container"> 
     <InputForm parentObject={this}></InputForm> 
     <TodoItems entries={this.state.items} /> 
     </div> 
    ); 
    } 
} 

class InputForm extends React.Component { 

this.onSubmit = this.onSubmit.bind(this); 
this.onInput = this.onInput.bind(this); 


onSubmit() 
{ 
    //invoking parent component function directly by passing parameter to it. 
    this.props.parentObject.addTodo(this.state.value); 
} 

onInput(e) { 
    this.setState({ 
     input: e.target.value 
    }); 
    } 

    render(){ 
    return (
     <form onSubmit={this.props.onSubmit}> 
     <input 
      value={ this.state.value } 
      onChange={ this.onInput } 
      ref="todoInput" 
      type="text" 
      placeholder="Type your text here" /> 
     <button type="submit">Add to list</button> 
     </form> 
    ) 
    } 
} 
関連する問題