React 动态创建的 child 组件未收到新道具
React dynamically created child component not receiving new props
我正在尝试遵循 React 的 "Stateless children, stateful parent" 思想,它运行得很好......直到我开始动态创建 children,也就是说。
这是我的代码的简化版本(CoffeeScript + JSX),它说明了我的困境:
@FormBlock = React.createClass
getInitialState: ->
fields: [], editMode: false
toggle: ->
@setState editMode: !@state.editMode
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
按钮将editMode
更改为true
时,<EditableText>
组件的内容将从<span>
更改为<input>
,这样用户可以对其进行更改。
这对 <FormBlock>
的 render
方法(即 <EditableText text="WORKS".../>
)中包含的虚拟组件非常有效,但这对 children 无效。我已经测试过,在创建时,每个 <EditableText>
类型的 child 都会收到其初始 props
,但是当 state.editMode
被修改时,所有 children 都会保留不变(我已经验证 componentWillReceiveProps
不会在 children 上触发,但会在虚拟元素上触发)。
我无计可施地试图解决这个问题。请帮忙!!!
您的问题是调用EditableText 的结果保存在组件状态中。如果您想根据状态动态渲染子组件,请改为在 render 方法中执行:
@FormBlock = React.createClass
getInitialState: ->
fields: [], editMode: false
toggle: ->
@setState editMode: !@state.editMode
addChild: ->
items = @state.fields.concat {}
@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.map @renderChild }
</div>`
renderChild: ->
`<EditableText
key={Date.now()}
text="FAILS"
editMode={this.state.editMode}/>`
我正在尝试遵循 React 的 "Stateless children, stateful parent" 思想,它运行得很好......直到我开始动态创建 children,也就是说。
这是我的代码的简化版本(CoffeeScript + JSX),它说明了我的困境:
@FormBlock = React.createClass
getInitialState: ->
fields: [], editMode: false
toggle: ->
@setState editMode: !@state.editMode
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
按钮将editMode
更改为true
时,<EditableText>
组件的内容将从<span>
更改为<input>
,这样用户可以对其进行更改。
这对 <FormBlock>
的 render
方法(即 <EditableText text="WORKS".../>
)中包含的虚拟组件非常有效,但这对 children 无效。我已经测试过,在创建时,每个 <EditableText>
类型的 child 都会收到其初始 props
,但是当 state.editMode
被修改时,所有 children 都会保留不变(我已经验证 componentWillReceiveProps
不会在 children 上触发,但会在虚拟元素上触发)。
我无计可施地试图解决这个问题。请帮忙!!!
您的问题是调用EditableText 的结果保存在组件状态中。如果您想根据状态动态渲染子组件,请改为在 render 方法中执行:
@FormBlock = React.createClass
getInitialState: ->
fields: [], editMode: false
toggle: ->
@setState editMode: !@state.editMode
addChild: ->
items = @state.fields.concat {}
@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.map @renderChild }
</div>`
renderChild: ->
`<EditableText
key={Date.now()}
text="FAILS"
editMode={this.state.editMode}/>`