私はReactの「ステートレスな子、ステートフルな親」のイデオロギーに従うようにしています。ここ動的に作成された子コンポーネントが新しい小道具を受け取っていない
私の苦境を示して自分のコード(のCoffeeScript + JSX)の簡易版であるこの例では
@FormBlock = React.createClass
getInitialState: ->
fields: [], editMode: false
toggle: ->
@setState editMode: [email protected]
addChild: ->
child = `<EditableText key={Date.now()} text="FAILS" editMode={this.state.editMode}/>`
items = @state.fields.concat child
@setState fields: items
render: ->
`<div>
<a onClick={this.toggle}>Change Mode</a><br/>
<a onClick={this.addChild}>Add Child</a><br/>
<EditableText text="WORKS" editMode={this.state.editMode}/><br/>
{this.state.fields}
</div>`
@EditableText = React.createClass
render: ->
if @props.editMode
`<input className="editable" defaultValue={this.props.text}/>`
else
`<span className="editable">{this.props.text}</span>`
、成分<FormBlock>
は最初fields
そのeditMode=false
全く含まないであろう。 Change Mode
ボタンをクリックしてをtrue
に変更すると、<EditableText>
コンポーネントの内容は<span>
から<input>
に変更され、ユーザーが変更できるようになります。
<FormBlock>
のrender
メソッド(つまり<EditableText text="WORKS".../>
)に含まれるダミーコンポーネントは完全に機能しますが、これは子供にとっては機能しません。私は作成時にタイプ<EditableText>
のすべての子どもがその最初のprops
を受け取ることをテストしましたが、state.editMode
が変更されたとき、すべての子どもは変更されません(私はcomponentWillReceiveProps
が子どもに対して発射しないことを確認しました。 )。
私はこの問題を解決しようとしています。助けてください!!!
おかげで、これは動作しません:あなたは動的状態に基づいて、子コンポーネントをレンダリングしたい場合は、代わりにrenderメソッドで行います親が更新されたときに更新されます)。あなたのバージョンの 'addChild'は新しい子をリストに追加しません。親のレンダリングメソッドで子をレンダリングするというあなたの提案については、私のコードスニペット '{this.state.fields}'はすでにこれを行っています。 'map'メソッドを使うのは本質的に同じですが、もっと冗長です。 – Vadim
あなたは部分的に正しいです。あなたのアプローチと上記の説明との大きな違いは、親のrenderメソッドが呼び出されたときに子コンポーネントが再レンダリングされるのに対し、子コンポーネントのrenderメソッドが呼び出された結果が親の状態であり、単にレンダリングされる代わりに呼び出されるだけである。 – Niko
私の例がうまくいかない理由は、現在のタイムスタンプをキーとして使用しているからです。 renderChildメソッドを呼び出すには、数ミリ秒の時間がかかります。このように、提供されるタイムスタンプはすべてのeditableTextインスタンスで同じであり、Reactのリコンシリエーションアルゴリズムはすべての要素を重複キーでフィルタリングし、EditableTextコンポーネントのインスタンスを1つだけ残します。実際の例が見つかりました[ここ](https://jsfiddle.net/1eur6xkd/) – Niko