React 组件无法同步由动态 ReactDOM.render 创建的道具
React component could not sync props which created by dynamic ReactDOM.render
当我使用 React+Redux+Immutable 时,我遇到了一个问题:通过动态方式创建的组件,当 props 更改时,组件不会重新渲染。是反应错误吗?
我删除了业务代码,只是这里的 React 代码:http://codepen.io/anon/pen/GoMOEZ
或以下:
import React from 'react'
import ReactDOM from 'react-dom'
class A extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'tom'
}
}
dynamic() {
ReactDOM.render(<B name={this.state.name} changeName={this.changeName.bind(this)} type={false}/>, document.getElementById('box'))
}
changeName() {
this.setState({
name: 'tom->' + Date.now()
});
}
render() {
return <div>
top name: {this.state.name}
<B name={this.state.name} changeName={this.changeName.bind(this)} type={true}/>
<div id="box"></div>
<button onClick={this.dynamic.bind(this)}>dynamic add component</button>
</div>
}
}
class B extends React.Component {
render() {
return <div>
{this.props.type ? '(A)as sub component' : '(B)create by ReactDOM.render'}
- name:【{this.props.name}】
<button onClick={this.props.changeName}>change name</button>
</div>
}
}
ReactDOM.render(
<A/>,
document.getElementById('example')
);
这不是一个错误,它只是不是做你想做的事的反应方式。每次调用A.render
都将覆盖<div id="box">...</div>
删除A.dynamic
添加的元素。
更惯用的方法是添加一些标志,将其设置onClick
处理程序中,并在A.render
中使用它来决定<div id="box">
是否应该为空。
请参阅代码笔上编辑的代码:http://codepen.io/anon/pen/obGodN
相关部分在这里:
class A extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'tom',
showB: false // new flag
}
}
changeName() {
this.setState({
name: 'tom->' + Date.now()
});
}
// changing flag on button click
showB() {
this.setState({showB: true})
}
render() {
// `dynamic` will contain component B after button is clicked
var dynamic;
if(this.state.showB) {
dynamic = <B
name = {this.state.name}
changeName = {this.changeName.bind(this)}
type = {false} />
}
return <div>
top name: {this.state.name}
<B name = {this.state.name}
changeName = {this.changeName.bind(this)}
type = {true}/>
<div>{dynamic}</div>
<button onClick = {this.showB.bind(this)}>
dynamic add component
</button>
</div>
}
}
更新
您仍然可以使用您的方法,但您需要手动更新动态创建的组件。
例如,您可以在changeName
函数中手动重新渲染它。
changeName() {
this.setState({
name: 'tom->' + Date.now()
}, this.dynamic.bind(this));
}
请注意,this.dynamic
作为第二个参数传递以this.setState
这可确保在状态真正更新时调用它。只需在this.setState({...})
之后添加this.dynamic()
将使用尚未更新的状态。
代码笔在这里: http://codepen.io/anon/pen/EPwovV
相关文章:
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 为effect Composer创建GodRays效果过程
- 从javascript创建一个列表
- onkeyup无法动态创建多个文本区域
- 如何使用javascript从主svg对象动态创建svg视图框
- 如何访问声音管理器2创建的声音对象
- 我已经创建了一个jquery转盘,并使用if条件来运行和停止转盘
- Kendo:我该如何在树视图中创建一个递归的hieiarchy
- 使用Facebook live API创建实时视频对象时的隐私设置
- 在动态创建的元素上获取对特定选择器的引用
- 如何创建带有插槽的vue js组件预加载程序
- 如何在创建键时引用来自同一对象的键
- 如何创建JSON数组
- 从html创建一个指令,该指令按类名应用函数
- 使用Javascript创建测验页面
- 更改使用Chart.js创建的图表中的轴线颜色
- JavaScript名称空间和对象创建
- React 组件无法同步由动态 ReactDOM.render 创建的道具
- 如何创建在res.render(模板渲染)之前运行的Express中间件
- 只有ReactOwner才能拥有refs.您可能正在向组件添加一个ref,而该ref不是在组件的render方法中创建的