问题描述
我是javascript和React新手,所以我对React概念的思考仍然有些困惑。
我试图在React中创建简单的对象检查器。
这是属性行元素:
class PropertyRow extends React.Component {
constructor(props) {
super(props);
this.state = {
propertyName: this.props.propertyName,
propertyValue: this.props.propertyValue
};
alert(this.props.propertyName + " evoked in constructor");
}
render() {
return (
<div>{this.props.propertyName} = {this.props.propertyValue}</div>
// <div>{this.state.propertyName} = {this.state.propertyValue}</div>
);
}
}
在组件PropertyRows的这里,我试图动态读取对象的所有属性。
class PropertyRows extends React.Component {
constructor(props) {
super(props);
this.createProRows = this.createProRows.bind(this);
}
createProRows(obj) {
const propArr = [];
for (const key of Object.keys(obj)) {
const val = obj[key];
propArr.push(<PropertyRow propertyName={key} propertyValue={val} />);
}
return propArr;
}
render() {
return <div>{this.createProRows(this.props.obj)}</div>;
}
}
在这里,我测试了这个很棒的代码
class Express extends React.Component {
constructor(props) {
super(props);
this.state = {
soldiers: 0,
captain:'John Maverick'
};
this.doClick = this.doClick.bind(this);
}
doClick() {
const obj = {
soldiers: this.state.soldiers + 1,
country:'Australia' //add new property
};
this.setState(obj);
}
render() {
return (
<div onClick={this.doClick}>
<PropertyRows obj={this.state} />
</div>
);
}
}
ReactDOM.render(<Express />, document.getElementById("root"));
当您单击文本时,将看到“士兵”属性增加一。 代码是错误的,我不知道为什么,或者也许我知道,但是我也不是完全不知道如何在React metalanguage中解决它。
-
我希望动态创建的
<PropertyRow propertyName={key} propertyValue={val}/>
数组将是浏览对象属性的好方法。 但是看起来,呈现的HTML DOM对象没有被销毁和重新创建。 当要表达doClick
函数中的新对象时,它们神秘地重新连接。
此外
在
doClick
创建另一个对象时,属性obj.captain
仍然存在(在浏览器窗口中),这可能是因为基础HTML DOM元素没有被破坏。 添加新的物业country: 'Australia'
似乎可以正常运行。当我第二次调用
<PropertyRow propertyName={key} propertyValue={val}/>
时,该构造函数将被触发,因为它是在新数组中创建并推送的。 但事实并非如此。 仅针对新的房地产country: 'Australia'
触发
看来,我必须以某种方式销毁渲染的HTML DOM元素,以强制做出反应来重新创建它们。 但是如何? 还是有另一种方法?
对于这篇长篇文章,我深表歉意。 我希望阅读起来不会那么复杂。
感谢名单
1楼
delete obj.captain
不执行任何操作,因为obj
没有captain
键。
captain
键存在于this.state
,因此不建议将其删除,因为React状态通常是不可变的。
与this.state
一起使用this.setState
可能会导致争用条件,应改用函数。
它应该是:
doClick() {
this.setState(state => ({
soldiers: state.soldiers + 1,
country:'Australia',
captain: undefined
}));
}
PropertyRow
的问题在于,它在构造函数中一次处理道具。
PropertyRow
构造函数仅被触发一次,因为该组件已经被挂载,现在仅在新的道具上进行更新(这是React生命周期挂钩的 )。
如果状态应该从收到的道具派生,则应使用 ,它在初始渲染和下一次更新之前映射道具的状态。 在这种情况下,不需要状态,因为状态属性和道具没有区别。 拥有:
class PropertyRow extends React.Component {
render() {
return (
<div>{this.props.propertyName} = {this.props.propertyValue}</div>
);
}
}
而且PropertyRow
可以重写为功能组件,因为它不能从类中受益。