2016-09-22 23 views
0

私はReactに非常に新しいです(これは非常に些細かもしれません)。単純なアプリケーションで試してみると、子コンポーネント内の親コンポーネントの状態を変更しようとすると固くなります。親コンポーネントの状態を子から変更する

アプリが動作するためには、親コンポーネントは状態が他のコンポーネントに引き継がれたときにその状態を維持する必要があります。したがって、私は子供に渡す状態変更機能を作成しました。

JS:

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     status: [ 
     { 
      id: 1, 
      name: 'Item 1', 
      selected: false 
     }, { 
      id: 2, 
      name: 'Item 2', 
      selected: false 
     }] 
    } 
    } 

    addItem(name) { 
    let id = this.props.status.length + 1; 
    let newItem = this.props.status; 
    newItem.push({id, name, selected: true}); 
    this.setState({ 
     status: newItem 
    }); 
    } 

    render() { 
    return (
     <div><ItemList status={this.state.status} addItem={this.addItem} /></div> 
    ); 
    } 
} 

class ItemList extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     search:'', 
    }; 
    } 

    handleAddSubmit(event) { 
    event.preventDefault(); 
    let name = this.refs.newit.value; 
    this.props.addItem(name); 
    this.refs.newit.value=''; 
    } 

    updateSearch(event) { 
    this.setState({search: event.target.value}); 
    } 

    render() { 
    let filteredItems = this.props.status.filter((item)=> { 
     return item.name.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1; 
    }); 
    return (
    <div> 
     <div> 
      <input placeholder="Search" type="text" 
      value={this.state.search} 
      onChange={this.updateSearch.bind(this)}/> 
     </div> 
     <div> 
      {filteredItems.map((item) => { 
      return (<button id={item.id}>{item.name}</button> 
      ); 
      })} 
      <form onSubmit={this.handleAddSubmit.bind(this)}> 
      <input type="text" placeholder="enter your item" ref="newit"/> 
      </form> 
     </div> 
     </div> 
    ); 
    } 
} 


ReactDOM.render(<App/>, document.getElementById('app')); 

HTML:以下のコードを参照してください

<div id="app"></div> 

私はコードが間違っているかを理解し、のaddItem関数は状態にアクセスすることはできませんが、私はどのようにわかりませんそれを修正する。親から子への状態を小道具として渡してから、addItemへの変数としてバックアップしようとしましたが、どちらも機能しません(下記のコードを参照)。さらに、私は成功したことなしに.bind(this)と.bind(null)で遊んできました(私はReact autoとthisバインドの違いは分かりません)。

addItem(oldStatus, name) { 
    let id = oldStatus.length + 1; 
    let newItem = oldStatus; 
    newItem.push({id, name, selected: true}); 
    this.setState({ 
     status: newItem 
    }); 
    } 

私は、可能ではない、推奨できないこと、または単なる単純なエラーであるかどうかはわかりません。私はここで多くの質問と公式チュートリアルをチェックしましたが、(私の場合はidを計算するために)状態にアクセスしようとするのとは対照的に、関数に渡されるパラメータを使ってsetStateを設定するだけです。私はこれを基本概念であると信じているが解決策を見いださなかったので、様々なチュートリアルを調べた。

ありがとうございました。

ベスト、

M

編集:私は、コードでjsfiddleを作成しました:https://jsfiddle.net/magp/cw8h2pzk/4/

答えて

2

あなたがエラーを表示するためにコンソールを開くことができます。

addItemを.bind(this)でバインドしていないというエラーがありました。

これは、渡されたメソッドにバインドする必要があります。それらはdomまたは他のコンポーネントで呼び出される可能性があるため、このコンテキストが変化します。しかし、渡している間にこれをバインドすると、これのコンテキストがコンポーネントになります。 this.state ...ステートメントは期待どおりに動作します。

また、すべての子供が固有のキーを持つ必要があります。

これは、配列をマッピングしている場合や、データを繰り返してjsxを返す場合、返されるjsxには一意のキーが必要であることを意味します。

ここには作業中のjsfiddleがあります。変更箇所は次のとおりです。高速かつ包括的な答えを

<form onSubmit={this.handleAddSubmit.bind(this)}> 

{filteredItems.map((item) => { 
    return (<button id={item.id} key={item.id}>{item.name}</button); 
})} 

https://jsfiddle.net/8v2cu95x/1/

+1

感謝。これは私が2つのことを理解するのを助けました:1)私がしようとしているのは、アンチパターンではなく、意図されていることです.2)拘束力の仕組みを理解できません。誰かがこれを詳しく説明するリソースを指摘できれば、私はそれを高く評価します。ほとんどのチュートリアルでは、これに関する深い説明をスキップしているようです。再度、感謝します – mgp

関連する問題