reactjs - 在不渲染父组件 React js 的情况下重新渲染子组件
问题描述
我正在学习 React js。我需要从父组件重新渲染其中一个子组件。一种方法是我可以将 setState 用于矩阵,但作为父组件的整个矩阵将被重新渲染,而我只想重新渲染一个子组件。这已通过下面的代码添加。
Child.js
import React from 'react';
class Child extends React.Component {
constructor(props){
super(props);
this.state = {
text : ""
};
}
updateParent(text) {
if(text) {
this.setState({text : text});
}
}
render() {
return(
<div>Child {this.state.text}</div>
);
}
}
export default Child;
父.js
import React from 'react';
import Child from './Child'
class Parent extends React.Component {
constructor(props){
super(props);
this.state = {
table : [[<Child key={11}/>, <Child key={12}/>, <Child key={13}/>],
[<Child key={21}/>, <Child key={22}/>, <Child key={23}/>]],
i : 0,
j : 0
};
}
componentDidMount() {
this.timerID1 = setInterval(() => this.updateTable(), 1000);
}
updateTable() {
//this.state.table[this.state.i][this.state.j].updateParent("");
this.state.j++;
if( this.state.j % 3 == 0) {
this.state.i++;
this.state.i %= 2;
}
//this.state.table[this.state.i][this.state.j].updateParent("*");
// or tempTable[i][j] = <Child key={ij} text={"*"}/>; this.setState({table: tempTable});
this.state.j++;
}
createTable() {
let table = []
for(let i = 0; i < 2; i++) {
table.push( <div key={i} style={{display:"flex"}}>{this.state.table[0]}</div> )
}
return table;
}
render() {
return(
<div>{this.createTable()}</div>
);
}
}
export default Parent;
解决方案
不要将子组件实例存储在状态中,而是动态渲染它们
您可以将 Child 实现为 PureComponent ,这样如果它没有任何道具或状态更改,它就不会重新渲染
不要像你一样直接改变状态
this.state.j++
等等。使用 setState
父.js
export default class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
table: this.createTableData(3),
i: 0,
j: 0
};
}
createTableData(size) {
const arr = new Array(size);
for (var i = 0; i < size; i++) {
arr[i] = new Array(size).fill("");
}
return arr;
}
componentDidMount() {
this.timerID1 = setInterval(() => this.updateTable(), 1000);
}
componentWillUnmount() {
clearInterval(this.timerID1);
}
updateTable() {
let { i, j, table } = this.state;
j++;
if (j % 3 == 0) {
i++;
i %= 2;
}
const newTable = table.map((tr, row) => {
return tr.map((td, col) => {
if (row == i && col == j) {
return "*";
} else {
return "";
}
});
});
j++;
this.setState({
table: newTable,
i,
j
});
}
createTable() {
return this.state.table.map((row, i) => {
return (
<div className="row">
{row.map((col, j) => {
return <Child key={`${i + 1}${j + 1}`} text={col} />;
})}
</div>
);
});
}
render() {
return <div>{this.createTable()}</div>;
}
}
Child.js
class Child extends React.PureComponent {
render() {
console.log("child rerender", this.props.text);
return <div>Child {this.props.text} </div>;
}
}
注意: demo 仅包含显示和性能优化逻辑以及架构,更新索引 i、j 的逻辑需要您在 updateTable 方法中完成。
如果你看演示,只有你的值从“”变为“*”的单元格会重新渲染,其余的不会
推荐阅读
- apache-spark - 如何在 Neo4j 中使用 Spark?
- android - 从后台恢复后Android应用程序崩溃
- python - cv2.imread 更改图像中的 base64 字符串并在操作系统之间生成不同的结果
- android - Android 低分辨率屏幕 Webview 渲染问题
- mysql - SQL 与其他 DBMS 的关系是什么?
- java - 如何获得两个值的和、差、商、乘积并在 textview 中打印出来
- android - JSONArray 保持为空,直到单击菜单项
- python - 在 Geodjango 中通过几何相交关联两个模型
- angular - 我正在使用 *ngFor 来迭代卡片布局中的元素。我想随机改变他们的背景颜色有什么办法吗?
- mysql - 查询以从一个表中生成不同设备的故障日志,在该表中设备输入其状态并带有时间戳