gpt4 book ai didi

javascript - useState() 钩子(Hook)在设置新值时从对象中删除字段

转载 作者:行者123 更新时间:2023-12-04 08:12:24 27 4
gpt4 key购买 nike

无法理解我在这里做错了什么。我有一个非常简单的对象状态:

const [itemInput, setItemInput] = useState({
userId: userId,
objectId: id,
title: "",
description: "",
createdAt: new Date().getTime().toString(),
})
然后,我有一个更改 title 的输入。 field :
const onChange = (e) => {
setItemInput((prevState) => ({
...prevState,
[e.target.name]: e.target.value,
}));
};
这就是 onChange用来:
<input
type="text"
className="item-description-input"
placeholder="Add description..."
name="title"
value={itemInput.title}
onChange={onChange}
/>
GraphQL 端点:
export const CREATE_ITEM = gql`
mutation createItem($itemInput: ItemInput!) {
createItem(itemInput: $itemInput) {
userId
objectId
title
description
createdAt
}
}
`;
提交功能:
const onAddItemClick = (e) => {
e.preventDefault();
createItem({
variables: {
itemInput: itemInput,
},
}).then((res) => {
console.log(res);
});
};
提交时,我得到:
message: "Variable "$itemInput" got invalid value { title: "ddd" }; Field "userId" of required type "MongoId!" was not provided." 
并且对于所有剩余字段重复此错误,但 title .
如果我 console.log(itemInput)当功能组件被加载时,我得到了对象的初始状态。但是,如果我添加 console.log(itemInput)onChange 之后, 我只得到 {title: "some_added_text"} . onChange 从对象中删除其他字段,并且在提交时,我的 graphQL 端点返回未提供其他字段的错误。这非常令人沮丧,因为我似乎做的一切都是正确的。
UPD:添加了组件。 Object组件获取对象列表。每个 ObjectItems .有问题的代码在 Items当我想添加一个新的组件时 Item到那个 Object .
对象(父)组件:
import React, { useState, useReactiveVar, Fragment } from "react";
import { useMutation } from "@apollo/client";
import CREATE_OBJECT from "../../mutations/Object";
import { objectsVar } from "../../cache";

//Components
import ItemContainer from "./ItemContainer";

const Container = ({ data, userId, color }) => {
const [objectInput, setobjectInput] = useState({
title: "",
userId: userId,
createdAt: new Date().getTime().toString(),
color: color,
});

const [createObject] = useMutation(CREATE_OBJECT);

const onAddClick = (e) => {
e.preventDefault();
createObject({
variables: {
objectInput: objectInput,
},
}).then((res) => {
setobjectInput({
title: "",
userId: userId,
createdAt: new Date().getTime().toString(),
color: color,
});
});
};

// This works perfectly fine!!
const onChange = (e) => {
setobjectInput({ ...objectInput, [e.target.name]: e.target.value });
};

objectsVar(data);
const objects = useReactiveVar(objectsVar);

return (
<div>
<div>
<input
type="text"
placeholder="Add description..."
name="title"
value={objectInput.title}
onChange={onChange}
/>
</div>
<div onClick={onAddClick}>Add object</div>
{objects && objects.getAllObjects.length === 0 ? (
<p>No objects</p>
) : (
<Fragment>
{objects &&
objects.getAllActiveSwimlines.map(({ _id, title, items }) => (
<ItemContainer key={_id} id={_id} title={title} userId={userId} items={items} />
))}
</Fragment>
)}
</div>
);
};

export default Container;
项目(子)组件:
import React, { useState, Fragment } from "react";
import ItemContainer from "../Item/ItemContainer";
import { useMutation } from "@apollo/client";
import { CREATE_ITEM } from "../../mutations/Item";

const ItemContainer = ({ id, title, items, userId }) => {
const [itemInput, setItemInput] = useState({
userId: userId,
objectId: id,
title: "initial state",
description: "test desc",
createdAt: new Date().getTime().toString(),
});

// This doesn't work!
const onChange = (e) => {
const { name, value } = e.target;
setItemInput({
...itemInput,
[name]: value,
});
};

const [createItem] = useMutation(CREATE_ITEM);

const onAddItemClick = (e) => {
e.preventDefault();
createItem({
variables: {
itemInput: itemInput,
},
}).then((res) => {
setItemInput({
userId: userId,
objectId: id,
title: "",
description: "",
createdAt: new Date().getTime().toString(),
});

console.log(res);
});
};

const newItemInput = (
<div>
<input
type="text"
placeholder="Add description..."
name="title"
value={itemInput.title}
onChange={onChange}
/>
<div onClick={onAddItemClick}>Add item</div>
</div>
);

const itemContent = (
<div>
<Fragment>
{items &&
items.getObjectItems.map(({ _id, title }) => (
<Item key={_id} id={_id} title={title} />
))}
</Fragment>
</div>
);

return (
<div>
{newItemInput}
{itemContent}
</div>
);
};

export default ItemContainer;
我在这里想念什么?

最佳答案

因为您访问e.target.namee.target.value在您的更新函数中,它们不会立即被评估,并且当他们这样做时,合成事件对象已被重用。如果你想保持其余代码不变,你可以通过调用 e.persist() 来修复它。在 onChange 的开头,或复制事件中的相关信息:

  const onChange = (e) => {
const {name, value} = e.target
setItemInput((prevState) => ({
...prevState,
[name]: value,
}));
};
或者,您可以放开更新功能,直接设置状态,(这在另一个被删除的答案中也有建议):
  const onChange = (e) => {
setItemInput({
...itemInput,
[e.target.name]: e.target.value,
});
};

关于javascript - useState() 钩子(Hook)在设置新值时从对象中删除字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65887087/

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