Loading... ## bug描述   - 如图,实时数据偶发性的不加载 ## 问题分析 - 数据源是常规的数组对象形式 - ``` { "id": 638, "equipment": "SN171-10", "equipment_sn": "0109_Z_B_DE00_0901018_T", "phase": "A相", "bay": "123B换流变A相", "bay_vol_level": "800kV", "manufacturer_code": "301", "manufacturer": "南网科研院", "sensor_type": "SVBR", "sensor_sn": "SN171-10", "mapperParam": [ { "do": "VbrAccAlm", "unit": "--", "desc": "振动加速度告警", "fc": 2, "data_type": "bool", "device_id": 638, "value": "false", "quality": 0, "frame_sn": 244863, "data_time": "1970-01-01 08:00:00", "received_time": "2022-05-25 16:50:18" }, { "do": "VbrDpmAlm", "unit": "--", "desc": "主控单元与传感器通信异常", "fc": 2, "data_type": "bool", "device_id": 638, "value": "false", "quality": 0, "frame_sn": 244863, "data_time": "1970-01-01 08:00:00", "received_time": "2022-05-25 16:50:18" } ] } ``` - 通过console.log排查,定位到问题所在,数据源拼装的时候数据丢失,数据源为device中的mapperParam - ``` // 动态数据组合 export const useCombinedDeviceData = (device, values) => { // 将数据值关联起来 return useMemo(() => { if (!device || !values) return device; device.mapperParam = device.mapperParam.map((item) => { let rowItem = values.find((ele) => ele.do === item.do); if (!rowItem) return item; if (item.data_type === 'float') { rowItem.value = formatNoneValue(rowItem.value, 3); } if (item.data_type === 'bool') { rowItem.value = rowItem.value.toString(); } return { ...item, ...rowItem }; }); console.log('device', device); return device; }, [device, values]); }; ``` - 入参device也是通过接口获取数据拼装后获得,拼装逻辑较多,所以准备直接在useCombinedDeviceData中做处理,该拼装逻辑中使用useMemo,且第二个依赖项含有数据源device,useMemode的第二个依赖项为浅比较,因此无法感知到mapperParam的变化,因此增加一个device?.mapperParam的依赖项,device?.mapperParam有一个重新赋值的操作,前后值的引用地址不一样 ## demo ``` // 父组件 //@ts-nocheck import { useState } from "react"; // import { Button } from "antd"; import Button from "./children.tsx"; const Demo = () => { const [name, setName] = useState("名称"); const [content, setContent] = useState("内容"); const [list, setList] = useState({ a: [1, 2, 3] }); return ( <> <button onClick={() => { setName(new Date().getTime()); const _list = list; _list.a = [4, 5, 6]; setList(_list); }} > name </button> <button onClick={() => setContent(new Date().getTime())}>content</button> <Button name={name} list={list}> {content} </Button> </> ); }; export default Demo; ``` ``` // 子组件 // const Button = ({ name, children }) => { // console.log(name); // function changeName(name) { // console.log("11"); // return name + "改变name的方法"; // } // const otherName = changeName(name); // function test() { // console.log("执行测试方法"); // } // test(); // return ( // <> // <div>{otherName}</div> // <div>{children}</div> // </> // ); // }; // export default Button; /* 优化后的组件 */ import { useMemo } from "react"; function Button({ name, children, list }) { function changeName(name) { console.log("11"); return name + "改变name的方法"; } const otherName = useMemo(() => changeName(name), [name]); function test() { console.log("执行测试方法", list); } useMemo(() => { test(); }, [list?.a]); return ( <> <div>{otherName}</div> <div>{children}</div> </> ); } export default Button; ``` ## Remark 用一个变量variable2存之前的变量variable1,并对variable2进行修改,再用variable2来更新(setstate)variable1,实质上引用地址没有发生变化(浅拷贝) 参考链接: - https://segmentfault.com/a/1190000018697490#comment-area ——侵删 - https://blog.csdn.net/weixin_43294560/article/details/110184755 ——侵删 最后修改:2022 年 05 月 26 日 © 允许规范转载 打赏 赞赏作者 赞 0 如果觉得我的文章对你有用,请随意赞赏