前言
在使用umi的hook——useModel时,setState的时候,视图不更新。
具体问题
目录结构
─ src
│ ├─ .umi
│ ├─ models
│ │ └─ users.ts
│ └─ pages
│ ├─ ModifyValue.tsx
│ ├─ index.less
│ └─ index.tsx
代码
//users.ts
import { useState } from 'react';
const useUsers = () => {
const [datas, setDatas] = useState([
{
id: 1,
name: 'john',
gender: 'm',
},
{
id: 2,
name: 'mary',
gender: 'f',
},
]);
return {
datas,
setDatas,
};
};
export default useUsers;
//ModifyValue.ts
import React from 'react';
import { useModel } from 'umi';
export default function ModifyValue() {
const { datas, setDatas } = useModel('users', (ret) => ({
datas: ret.datas,
setDatas: ret.setDatas,
}));
const updateFieldChanged = () => {
let newArr = [...datas]; // copying the old datas array
newArr[0].name = '123';
setDatas(newArr);
};
return <button onClick={updateFieldChanged}>modifyValue</button>;
}
//index.tsx
import { useEffect } from 'react';
import { useModel } from 'umi';
import ModifyValue from './modifyValue';
export default function IndexPage() {
const { datas } = useModel('users', (ret) => ({
datas: ret.datas,
}));
return (
<div>
{JSON.stringify(datas)}
<ModifyValue />
</div>
);
}
具体表现为:
问题分析:
- useModel的实现
2.分析在代码执行中state是如何变化的
因为let newArr = [...datas]只是进行了浅复制,所以只复制了datas中存放的地址值,所以当使用let newArr=[...data]去修改的时候是修改地址1当中存在的值,最后newArr和datas在比较的时候没有差别,所以就没有触发更新
解决方案
const updateFieldChanged = () => {
let newArr = [...datas]; // copying the old datas array
newArr[0] = {
...newArr[0],
name: '123',
}; //拷贝对象
setDatas(newArr);
};