gpt4 book ai didi

javascript - React js hooks lodash 设置奇怪的行为

转载 作者:行者123 更新时间:2023-12-02 21:41:42 25 4
gpt4 key购买 nike

我使用 lodash 能够将属性(对象、数组)的值更改到一定深度,但我有一个奇怪的行为。

情况是这样的,我使用带钩子(Hook)的react js,在状态下我有一个保存用户信息的对象,所以我做了一个fetch来加载处于名为状态的对象上的用户信息用户

但是,此信息不仅保存在 user 对象中,还保存在另一个名为 userInfo 的对象中,因此我有两次处于状态的信息,但不同的主格属性。

我需要两次获得这些信息,只是为了确保当用户想要更改他们的数据(个人资料页面)时,我检查他修改的数据是否确实被修改过,也就是说,至少有有一个元素与原始元素不同。

问题在于,当我编辑 user 上的数据时,它会更改 userInfo 上的相同数据,但我不明白原因。

最奇怪的是,这个问题只发生在我正在本地项目上,在codesandbox上制作一个简单的例子时,问题并没有发生。

问题似乎是由于 handleChangeField 函数引起的,但我不明白为什么只有本地发生。

你能帮我一下吗?

链接:codesandbox

代码:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";
import ReactJson from "react-json-view";
import lodash from "lodash";

const useStyles = makeStyles(theme => ({
root: {
"& > *": {
margin: theme.spacing(1),
width: 200
}
}
}));

export default function BasicTextFields() {
const classes = useStyles();

const [state, setState] = React.useState({
user: {
name: "James",
surname: "bond",
card: {
id: 7,
group: "J"
},
scope: [{ scope: "user", actions: ["create", "delete"] }]
},
userInfo: {
name: "James",
surname: "bond",
card: {
id: 7,
group: "J"
},
scope: [{ scope: "user", actions: ["create", "delete"] }]
}
});

const handleChangeField = field => ({ target: { value } }) => {
let newState = lodash.cloneDeep(state);
lodash.set(newState, field, value);
console.log(newState, state);
setState(newState);
};

console.log("Change", state);

return (
<form className={classes.root} noValidate autoComplete="off">
<ReactJson
src={state}
theme={"solarized"}
enableClipboard={false}
displayObjectSize={false}
/>

<TextField
id="standard-basic"
label="Name"
onChange={handleChangeField("user.name")}
/>
<TextField
id="standard-basic"
label="Group"
onChange={handleChangeField("user.card.group")}
/>
<TextField
id="standard-basic"
label="Action[0]"
onChange={handleChangeField("user.scope[0].actions[0]")}
/>
</form>
);
}

最佳答案

The problem where it is, that when I edit a data that is on user in turn it changes the same data on userInfo, but I don't understand the reason.

这告诉您 useruserInfo (或 user.carduserInfo.card)引用同一个对象在它发生的情况下:

const userDataFromAjaxOrWhatever = {
name: "James",
surname: "bond",
card: {
id: 7,
group: "J"
},
scope: [{ scope: "user", actions: ["create", "delete"] }]
};
const state = {
user: userDataFromAjaxOrWhatever,
userInfo: userDataFromAjaxOrWhatever
};

console.log(`state.user.name = ${state.user.name}`);
console.log(`state.userInfo.name = ${state.userInfo.name}`);
console.log("Setting state.user.name = Joe");
state.user.name = "Joe";
console.log(`state.user.name = ${state.user.name}`); // Joe
console.log(`state.userInfo.name = ${state.userInfo.name}`); // Joe

您引用的代码不会发生这种情况,因为 useruserInfo 指向不同的对象。我假设在您的实际代码中,您正在以不同的方式填充您的状态,而不是使用硬编码的对象文字。

不可能说出为什么 useruserInfo 指向同一个对象,因为您没有向我们展示发生这种情况的代码,但是您必须执行与上面的代码片段类似的操作:

const state = {
user: userDataFromAjaxOrWhatever,
userInfo: userDataFromAjaxOrWhatever
};

相反:

const state = {
user: userDataFromAjaxOrWhatever,
userInfo: lodash.cloneDeep(userDataFromAjaxOrWhatever)
};

那么你就不会遇到这个问题了:

const userDataFromAjaxOrWhatever = {
name: "James",
surname: "bond",
card: {
id: 7,
group: "J"
},
scope: [{ scope: "user", actions: ["create", "delete"] }]
};
const state = {
user: userDataFromAjaxOrWhatever,
userInfo: _.cloneDeep(userDataFromAjaxOrWhatever)
};

console.log(`state.user.name = ${state.user.name}`);
console.log(`state.userInfo.name = ${state.userInfo.name}`);
console.log("Setting state.user.name = Joe");
state.user.name = "Joe";
console.log(`state.user.name = ${state.user.name}`); // Joe
console.log(`state.userInfo.name = ${state.userInfo.name}`); // James
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

关于javascript - React js hooks lodash 设置奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60350984/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com