javascript - 在 React 中制作简单的对象检查器的几个问题
问题描述
我是 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 元语言中解决它。
- 我希望,动态创建的数组
<PropertyRow propertyName={key} propertyValue={val}/>
将是浏览对象属性的好方法。但看起来,呈现的 HTML DOM 对象并没有被破坏和重新创建。doClick
当要表达函数中的新对象时,它们会神秘地重新附加。
此外
当在 中创建另一个对象时
doClick
,该属性obj.captain
仍然存在(在浏览器窗口中),可能是因为底层 HTML DOM 元素没有被破坏。添加新属性country: 'Australia'
似乎工作正常。当我
<PropertyRow propertyName={key} propertyValue={val}/>
第二次调用时,我希望该构造函数会被触发,因为它是在新数组中创建并推送的。但事实并非如此。它仅针对新属性被解雇country: 'Australia'
看来,我必须以某种方式破坏呈现的 HTML DOM 元素才能强制做出反应以重新创建它们。但是怎么做?还是有其他方法?
对于这么长的文字,我深表歉意。我希望它不是那么复杂的阅读。
谢谢
解决方案
delete obj.captain
什么都不做,captain
因为obj
. captain
key 存在于 中this.state
,并且不鼓励从中删除它,因为 React 状态通常是不可变的。
this.state
与 with 一起使用可能this.setState
会导致竞态条件,应使用状态更新函数。
它应该是:
doClick() {
this.setState(state => ({
soldiers: state.soldiers + 1,
country:'Australia',
captain: undefined
}));
}
问题PropertyRow
在于它在构造函数中处理一次道具。PropertyRow
构造函数只被触发一次,因为组件已经被挂载,现在它只在新的道具上更新(这里是 React 生命周期钩子的示意图)。
如果一个状态应该从收到的 props 派生,则应该使用getDerivedStateFromProps
hook,它在初始渲染和下一次更新之前从 props 映射一个状态。在这种情况下,不需要状态,因为状态属性和道具没有区别。拥有以下就足够了:
class PropertyRow extends React.Component {
render() {
return (
<div>{this.props.propertyName} = {this.props.propertyValue}</div>
);
}
}
并且PropertyRow
可以重写为功能组件,因为它不能从类中受益。
推荐阅读
- c++ - 为什么在尝试使 i = i*i 时出现错误“使用未初始化的内存 'i'”和“使用了未初始化的局部变量 'i'”
- customization - 在 Acuamtica 升级后,通过客户休息时的事件处理程序更新位置上的自定义字段
- java - 第二次重新调用相同方法后出现 NullPointerException
- php - 如何在已编译的 php 上配置 mysqli?- 使用 aws lambda php 脚本教程编译
- gitlab - 如何使用变量设置动态 gitlab 作业标签?
- python - 给定外部坐标提取多边形的内部点
- java - linux 上的 java.library.path 中没有 mssql-jdbc auth-8.4.1.x64
- impala - 试图在 Impala 中将 varchar 转换为日期
- javascript - 在 drawImage IOS Safari 上使用视频元素的替代方法
- django - Django - 通过多对多上最近的表行加入