2017-03-02 7 views
0

私はReactJSを学んでいますが、私は分かりませんが、このエラーに直面しました。ReactJS - 定義されていないプロパティ 'items'を読み取ることができません

子のコンポーネントから親のitems配列状態を変更したいと考えています。 addItem関数を小道具としてchildrenコンポーネントに渡そうとしました。入力すると、子コンポーネントがこの関数を呼び出して入力値を渡します。

addItemメソッドでconsole.log(this.state.items)を試してみると、このエラーが発生します。

Uncaught TypeError: Cannot read property 'items' of undefined 

メインApp.js

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

    render() { 
     return (
      <div className="App"> 
       <p>Todo List</p> 
       <AddItemBox addNewItem={this.addItem}/> 
       <ItemsList items={this.state.items}/> 
      </div> 
     ); 
    } 

    addItem(item) { 
     var listItems = this.state.items; 
     listItems.push(item); 
     this.setState({items: listItems}); 
    } 
} 

子コンポーネント:AddItemBox.js

class AddItemBox extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      item: '' // input value 
     }; 
    } 

    render() { 
     return (
      <div className='AddItemBox'> 
       <input type='text' placeholder='add item' onChange={e => { 
       this.onInputChange(e.target.value) 
      }} onKeyPress={e => { 
       if (e.key === 'Enter') { 
        this.onInputEnter(e.target.value) 
       } 
      }}/> 
      </div> 
     ); 
    } 

    onInputChange(item) { 
     this.setState({item}); 
    } 

    onInputEnter(item) { 
     // Now add it to the 'items' array state 
     this.props.addNewItem(item); 
     this.setState({item: ''}); 
    } 
} 
+0

これをコンストラクタで行います: 'this.addItem = this.addItem.bind(this)' – Li357

+0

@AndrewLiああ、うまくいきました!もう少し説明していただけますか?ありがとうございました! – narulakeshav

+0

'bind'関数は' this'参照をクラス自体に(あるいは 'this'がその時点であったものに)変更して、' state'を参照することができます。それがなければ、 'this'は関数を呼び出したものを参照します。 –

答えて

1

私は@AndrewLiを説明するのに役立つことができます。このarticleをチェックしてください。 Reactで関数をバインドする必要がある理由の中間を説明します。簡単な説明はscopeになります。

addItem関数内にはthisとは何ですか?それはあなたが期待するものではないかもしれません。したがって、適切なthisを関数にバインドする必要があります。たとえば、this.state.itemsのように、意図したとおりに使用できます。 thisが期待どおりのthisでない場合、望ましくない結果が得られます。

constructor(props) { 
 
     super(props); 
 
     this.state = { 
 
      item: '' // input value 
 
     }; 
 
     
 
     this.addItem = this.addItem.bind(this) 
 
    }

それとも、ES6を使用してこれを行うことができます:

だから、これを行うことができます

addItem = (item) => { 
 
    var listItems = this.state.items; 
 
    listItems.push(item); 
 
    this.setState({items: listItems}); 
 
}

どちらがあなたに同じを与えます結果

0

はまた、あなたは、コンストラクタ内の関数をバインドする必要があり

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

    render() { 
     return (
      <div className="App"> 
       <p>Todo List</p> 
       <AddItemBox addNewItem={(item) => this.addItem(item)}/> 
       <ItemsList items={this.state.items}/> 
      </div> 
     ); 
    } 

    addItem(item) { 
     var listItems = this.state.items; 
     listItems.push(item); 
     this.setState({items: listItems}); 
    } 
} 

として「AddItemBox」コンポーネントで、コールバックの代わりに、参照として関数を渡すことができます。

関連する問題