react组件数组元素属性发生变化时,setState页面不更新
今天遇到的问题是:组件内对数组元素进行修改后数据有变化但是页面没重新渲染话说这是因为组件没能够识别数组的变化,所以页面没有重新渲染所以只要让组件感知到你发生了改变,就可以达到刷新的效果import React, { Component } from 'react';import './App.css';import Todo from './components/todo/index'import
·
今天遇到的问题是:组件内对数组元素进行修改后数据有变化但是页面没重新渲染
话说这是因为组件没能够识别数组的变化,所以页面没有重新渲染
所以只要让组件感知到你发生了改变,就可以达到刷新的效果
import React, { Component } from 'react';
import './App.css';
import Todo from './components/todo/index'
import { Table, Button } from 'element-react';
class App extends Component {
constructor(props) {
super(props);
this.state = [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
render() {
return (
<div>
<Todo list={this.state.data}/>
<Table
style={{width: '100%'}}
columns={this.state.columns}
data={this.state.data}
/>
<Button type="primary" onClick={this.addData.bind(this)}>添加</Button>
</div>
);
}
addData () {
let obj = {
date: '2018-05-07',
name: '小明',
address: ''
};
let data = this.state.data;
data.push(obj);
this.setState({
data: data
});
console.log(this.state);
}
}
export default App;
上面代码中 通过setState设置data的值发现视图并没有更新,原因是数组的赋值是引用传递的,data = this.state.data其实是将this.state.data的内存地址复制给了data,所以执行data.push(obj)实际上相当于执行了 this.state.data.push(obj),因为地址指向一个地方,所以react的虚拟dom发现state里面的data没有变化,所以不更新视图,而这时可以使用一个新数组:
let data = [...this.state.data];
同理,React Hook也会发生上述问题
import React, { useState, useEffect } from "react";
import TestItem from "../TestItem/TestItem.js";
import Count from "../count";
const _ = {
map: require("lodash/map"),
fill: require("lodash/fill"),
set: require("lodash/set")
};
const Main = () => {
const [name, setName] = useState("");
const [count, setCount] = useState(0);
const [datas, setDatas] = useState([]);
const getDatas = () => {
setDatas([
{ title: "分类一", index: 0 },
{ title: "分类二", index: 1 },
{ title: "分类三", index: 2 }
]);
};
useEffect(() => {
setName("hello world");
getDatas();
}, []);
useEffect(() => {
console.log("data has changed !!!!!");
}, [datas]);
const onClick = index => {
const result = _.set(datas, [index, "title"], "哎呀我去");
// ❌错误的方式
// setDatas(result)
// 方法一
// setDatas(JSON.parse(JSON.stringify(result)));
// 方法二
// setDatas([...result]);
// 方法三
let tmp = [...datas]; // 切不可 let tmp = datas
tmp[index].title = "哈哈哈哈";
setDatas(tmp);
// 方法四
//使用lodash的_.cloneDeep()
};
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<div>
{datas.map((item, index) => {
return <TestItem data={item} key={index} onClick={onClick} />;
})}
</div>
<div>
<Count count={count} handleClick={handleClick} />
</div>
</div>
);
};
export default Main;
涉及到的知识点是对象的深拷贝与浅拷贝,这里有一篇关于深拷贝与浅拷贝的文章很好,感兴趣的童鞋可以看一下哦~~js浅拷贝与深拷贝的区别和实现方式
更多推荐
已为社区贡献1条内容
所有评论(0)