2017-05-06 22 views
4

このcodeでは、単純なオブジェクト上でsetStateを正常に使用できます。「Joey」をクリックすると、名前が「Igor」に変わります。React JSの配列にネストされたオブジェクトで `setState`を使うにはどうすればいいですか?

class Card extends React.Component { 
     myFunc =() => {this.props.change('Igor')}; 
     render() { 
      return (
       <p onClick={this.myFunc}>{this.props.name}</p> 
      ) 
     } 
    } 

    class Parent extends React.Component { 
     constructor(props) { 
      super(props) 
      this.state = { name: "Joey" } 
     } 

     toggle = (newname) => { 
      this.setState((prevState, props) => ({ 
       name: newname 
      })); 
     } 

     render() { 
      return (
       <Card change={this.toggle} name={this.state.name} /> 
      ); 
     } 
    } 

しかし、配列内のネストされた複数のオブジェクトを持っているこのcode、と、setStateのいずれかではありません「イゴール」にそれぞれの名前を変更することができるか、それはいくつかの方法で変更する必要があります。

class Card extends React.Component { 

     myFunc =() => {this.props.change('Igor')}; 
     render() { 
      return (
       <p onClick={this.myFunc}>{this.props.name}</p> 
      ) 
     } 
    } 

    class Parent extends React.Component { 
     constructor(props) { 
      super(props) 
      this.state = { 
       names: [ 
        { 
         name: "Joey" 
        }, 
        { 
         name: "Sally" 
        }, 
        { 
         name: "Billy" 
        }, 
       ] 
      } 
     } 

     toggle = (newname) => { 
      this.setState((prevState, props) => ({ 
      // what can I put here to change the name I click on to "Igor" 
      })); 
     } 

     render() { 
      const names = this.state.names.map((name, index) => (
       <Card key={index} change={this.toggle} {...name} /> 
      )) 

      return (
       <div> 
        {names} 
       </div> 
      ); 
     } 
    } 

私は、これはsetState作品は、私がindexを渡し、その後this.state.names[index].name: newnameを書き込むことによってnameにアクセスしようとしない方法を知っているにもかかわらず。驚きはありませんが、うまくいきませんでした。

不変性ヘルパーに関して多くの言及がありましたが、私は研究しており、これに関する同様の質問は見つかりません。しかし、私はそれが行く方法であるかどうかまだ分かりません。

setStateを使用して配列にネストされたオブジェクトを変更する最も良い方法は何ですか?

+0

'this.setState(this.state)'? –

+0

クリックしたことをどのように知っていますか?特定の「カード」のインデックスなどの識別子が必要です。 – Li357

答えて

1

はあなたのコードを変更していると作業の例では、hereを見つけることができます。

変更はここで見つけることができます:

toggle = (index, newname) => { 
    this.setState((prevState, props) => ({ 
     // Return new array, do not mutate previous state. 
     names: [ 
      ...prevState.names.slice(0, index), 
      { name: newname }, 
      ...prevState.names.slice(index + 1), 
     ], 
    })); 
} 

render() { 
    const names = this.state.names.map((name, index) => (
     // Need to bind the index so callback knows which item needs to be changed. 
     <Card key={index} change={this.toggle.bind(this, index)} {...name} /> 
    )) 

    return (
     <div> 
      {names} 
     </div> 
    ); 
} 

アイデアは、あなたが.bind経由でコールバック関数へのインデックスを渡し、修正の名前で新しいstate配列を返す必要があるということです。コンポーネントがnameを変更するオブジェクトを知るように、インデックスを渡す必要があります。newname

+1

これは非常に役に立ちます。ありがとうございます。これは後で見るかもしれない他の人のために働いています**私は私の元の質問**で、[ここ](https:// daveceddia)で与えられた理由で '.bind(this) Tayの助けを借りて、私は[code](https://codesandbox.io/s/rk5mMP5L4)を ' .bind(this) 'です。 –

1

私は、トグル方式のためにこれを使用します。

toggle = (nameYouWantChanged, nameYouWantItChangedTo) => { 

    this.setState({ 
    names: this.state.names.map(obj => 
     obj.name === nameYouWantChanged 
     ? { name: nameYouWantItChangedTo } 
     : obj 
    ) 
    }) 

} 
+0

ブラッドさん、ありがとう、これはかなり賢いです。 7行目に ':obj'の後ろに' '' 'がありませんが、これは素晴らしい解決策です。私は自分の[code](https://codesandbox.io/s/YzRwAgy0)を変更し、他の人がこの問題の解決方法を見ることができるようにしました。 –

+0

Bradはまた、あなたが 'index 'を使うことで、配列内の複数のオブジェクトが同じ名前を共有しているような場合に、問題が発生しないようにして、Tayの解決方法を選択したことを知りたがっています。 –

関連する問題