我是ReactJS的新手。当我单击按钮时,呼叫将从createTablesam.js
转到index.js
以更新对象。对象已在setState
中成功更新,但在UI中未更新。如果再次单击该按钮,则对象正在更新,但UI未更新。
const PureComponent = React.PureComponent;
class Index extends PureComponent {
constructor() {
super();
this.state = {
userValues: [
{
name: "Mani",
age: 23,
skill: "Java"
},
{
name: "Vel",
age: 23,
skill: "react"
}
]
};
this.addRow = this.addRow.bind(this);
}
addRow() {
let newdetails = {
name: "ManiVEL",
age: 25,
skill: "REACT JS"
};
let userValues = this.state.userValues;
userValues.push(newdetails);
this.setState({
userValues
});
}
render() {
return (
<CreateTablesam
addtable={this.addRow}
tabelDeatils={this.state.userValues}
></CreateTablesam>
);
}
}
class CreateTablesam extends PureComponent {
state = {
tableCopy: this.props.tabelDeatils
};
render() {
const createRow = this.state.tableCopy.map(per => (
<tr key={per.name}>
<td>{per.name}</td>
<td>{per.age}</td>
<td>{per.skill}</td>
</tr>
));
return (
<div>
<table>
<thead>
<tr>
<td>Name</td>
<td>Age</td>
<td>skills</td>
</tr>
</thead>
<tbody>{createRow}</tbody>
</table>
<button onClick={this.props.addtable}>CLICK</button>
</div>
);
}
}
ReactDOM.render(<Index />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
我犯了什么错误?
答案 0 :(得分:0)
您需要改进更新状态数组的方式。如评论部分所述,请阅读Correct modification of state arrays in ReactJS
在您的情况下,可能是:
this.setState({
userValues: [...this.state. userValues, newelement]
})
一旦您具有上述要点,就需要改进密钥处理部分。请阅读:Understanding unique keys for array children in React.js
原因是表中的数据具有相同的键key={per.name}
。由于您总是添加相同的记录,因此name
属性将保持不变。因此,<tr key={per.name}>
键将保持不变。尝试将不同的对象(至少具有不同的名称)添加到表中。
答案 1 :(得分:0)
您正在直接更改addRow
中的状态。复制userValues
或使用setState
的功能形式:
addRow() {
let newdetails = {
name: "ManiVEL",
age: 25,
skill: "REACT JS"
};
this.setState(state => {
return {
userValues: [...state.userValues, newdetails]
}
});
}
// or
addRow() {
let newdetails = {
name: "ManiVEL",
age: 25,
skill: "REACT JS"
};
this.setState({
userValues: [...this.state.userValues, newdetails]
});
}
编辑:您还需要直接使用道具,而不是将其分配给子组件中的状态:
class CreateTablesam extends PureComponent {
render() {
const createRow = this.props.tabelDeatils.map((per, i) => (
<tr key={i}>
<td>{per.name}</td>
<td>{per.age}</td>
<td>{per.skill}</td>
</tr>
));
return (
<div>
<table>
<thead>
<tr>
<td>Name</td>
<td>Age</td>
<td>skills</td>
</tr>
</thead>
<tbody>{createRow}</tbody>
</table>
<button onClick={this.props.addtable}>CLICK</button>
</div>
);
}
}
答案 2 :(得分:0)
React.PureComponent的shouldComponentUpdate()会跳过整个组件子树的道具更新。确保所有子组件也都是“纯”的。
这就是为什么您的道具不更新组件的原因。尝试使用React.Components
答案 3 :(得分:0)
您不必将道具复制到子组件中的状态。
addRow() {
let newdetails = {
name: "ManiVEL"+ Math.random(),
age: 25,
skill: "REACT JS"
};
this.setState({
userValues: [...this.state.userValues, newdetails]
});
}
还请确保您要在addtable函数中添加唯一项
{{1}}
答案 4 :(得分:0)
两个问题
this.state = ...
每个组件实例仅运行一次。而且,由于您将tabelDeatils
值存储在此处,因此它将永远不会更新。更改如下
const PureComponent = React.PureComponent;
class Index extends PureComponent {
constructor() {
super();
this.state = {
userValues: [
{
name: "Mani",
age: 23,
skill: "Java"
},
{
name: "Vel",
age: 23,
skill: "react"
}
]
};
this.addRow = this.addRow.bind(this);
}
addRow() {
let newdetails = {
name: "ManiVEL",
age: 25,
skill: "REACT JS"
};
this.setState({
userValues: [...this.state.userValues, newdetails]
});
}
render() {
return (
<CreateTablesam
addtable={this.addRow}
tabelDeatils={this.state.userValues}
></CreateTablesam>
);
}
}
class CreateTablesam extends PureComponent {
render() {
const createRow = this.props.tabelDeatils.map((per, idx) => (
<tr key={idx}>
<td>{per.name}</td>
<td>{per.age}</td>
<td>{per.skill}</td>
</tr>
));
return (
<div>
<table>
<thead>
<tr>
<td>Name</td>
<td>Age</td>
<td>skills</td>
</tr>
</thead>
<tbody>{createRow}</tbody>
</table>
<button onClick={this.props.addtable}>CLICK</button>
</div>
);
}
}
ReactDOM.render(<Index />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
编辑
如注释中所述,在循环中生成元素时需要添加唯一键。我已经在数组中添加了索引,但是不建议这样做。您需要找到每个元素唯一的东西,并将其作为键传递。