useState只修改接口的一个字段
Modify only one field of the interface with the useState
我定义了这个接口并进行了初始化:
interface userInterface {
email:string
name:string
last_name:string
}
const [userData, setUserData] = useState <userInterface> ({
email:"",
name:"",
last_name:"",
})
那么如果您只想更改名称。应该如何使用 setUserData 来完成?
也就是说,我想保留电子邮件和last_name,但只修改名称
简单的例子:
setUserData((prev) => ({ ...prev, name: 'Name you want' }));
const { useState } = React;
const DemoComponent = () => {
const [userData, setUserData] = useState({
email: "",
name: "",
last_name: ""
});
const handleBtnOnClick = (name) => {
setUserData((prev) => ({ ...prev, name: name }));
};
return (
<div>
<button
onClick={() => {
handleBtnOnClick("Jay");
}}
>
Jay
</button>
<button
onClick={() => {
handleBtnOnClick("Andy");
}}
>
Andy
</button>
<button
onClick={() => {
handleBtnOnClick("Olivia");
}}
>
Olivia
</button>
<div>{JSON.stringify(userData, null, "\t")}</div>
</div>
);
}
ReactDOM.render(
<DemoComponent />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
@Jay Lu 说的对
我想注意几件事。
打字稿接口
- 接口名称应使用 PascalCasing
- 键名应使用驼峰式
- 在适当的地方优先使用实用程序类型
[optional]
接口名称应以大写“I”开头
- 这曾经是一个惯例,现在越来越多的人正在远离它。您的选择
界面更新:1) 命名约定
interface UserInterface {
email:string
name:string
lastName:string
}
接下来我们要做的是使用实用程序类型来简化代码的冗长。
界面更新:2) 实用程序类型
我们实际上会将此接口更改为一种类型,以便轻松使用实用程序类型 Record
.
type UserInterface = Record<"email" | "name" | "lastName", string>;
至于你的组件,你没有在那里提供太多细节,所以我将提供有关设置状态的详细信息。
功能组件:更新状态
确定您需要“订阅”更改的变量或数据非常重要。例如,如果电子邮件和姓名是静态的(永不更改),则无需将它们置于会导致状态变量默认为空字符串的状态:
const [userData, setUserData] = useState("");
如果不是这种情况并且您确实需要更新和管理电子邮件、姓名和姓氏更新状态很简单:使用更新后的值传播现有状态。您可以使用从 useState 返回的元组中提供的 setter 函数来执行此操作。在本例中为 setUserData
。 setter 函数采用与默认 或 相同类型的值,它可以接受回调函数,它为您提供 current 状态值。这对于更新状态对象变量非常强大且非常有用。对于您的情况,我们有:
setUserData((previous) => ({...previous, name: "Updated name value"});
这里发生了什么?如果我们向 setUserData
传递回调,它会为我们提供“先前”状态。第一次调用此函数时,"previous" 是:
{
email: "",
name: "",
lastName: ""
}
我们正在获取该值并将其分布在具有更新值的 new 对象中。这与 Object.assign 相同。如果您传播对象中已存在的键,它将被替换。在我们传播我们的状态对象之后看起来像:
{
email: "", // didn't change because we didn't pass a new value
lastName: "", // didn't change because we didn't pass a new value
name: "Updated name value" // changed because we passed a new value
}
这意味着,如果您想更新电子邮件,只需执行以下操作即可:
setUserData((previous) => ({...previous, email: "hello@world.com"});
现在您的状态对象将是:
{
email: "hello@world.com",
lastName: "",
name: "Updated name value"
}
如果您再次使用回调调用 setUserData
,则之前的值将是上面的那个对象。
如果您想将其设置回原始值,您可以在不使用回调的情况下更新整个状态。为什么?因为我们不需要保留任何值,因为我们想覆盖它:
setUserData({ email: "", lastName: "", name: ""});
虽然有一点改进。如果我们决定在某个时候我们想要“重置为默认值”,我们应该将默认值存储在一个变量中并重新使用它。不是 100% 必要,但它可能是一个很好的更新,特别是如果你有一个复杂的组件。
关于 Typescript 强大功能的快速说明
如果您尝试使用之前未定义的新密钥更新状态,假设“helloWorld”打字稿会给您一个错误,因为“helloWorld”未在您的 UserData 类型中定义。
希望@Jay Lu 的回答和其中的一些信息有所帮助。如果您提供更多详细信息,我们可能会提供更多指导。
我定义了这个接口并进行了初始化:
interface userInterface {
email:string
name:string
last_name:string
}
const [userData, setUserData] = useState <userInterface> ({
email:"",
name:"",
last_name:"",
})
那么如果您只想更改名称。应该如何使用 setUserData 来完成?
也就是说,我想保留电子邮件和last_name,但只修改名称
简单的例子:
setUserData((prev) => ({ ...prev, name: 'Name you want' }));
const { useState } = React;
const DemoComponent = () => {
const [userData, setUserData] = useState({
email: "",
name: "",
last_name: ""
});
const handleBtnOnClick = (name) => {
setUserData((prev) => ({ ...prev, name: name }));
};
return (
<div>
<button
onClick={() => {
handleBtnOnClick("Jay");
}}
>
Jay
</button>
<button
onClick={() => {
handleBtnOnClick("Andy");
}}
>
Andy
</button>
<button
onClick={() => {
handleBtnOnClick("Olivia");
}}
>
Olivia
</button>
<div>{JSON.stringify(userData, null, "\t")}</div>
</div>
);
}
ReactDOM.render(
<DemoComponent />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
@Jay Lu 说的对
我想注意几件事。
打字稿接口
- 接口名称应使用 PascalCasing
- 键名应使用驼峰式
- 在适当的地方优先使用实用程序类型
[optional]
接口名称应以大写“I”开头- 这曾经是一个惯例,现在越来越多的人正在远离它。您的选择
界面更新:1) 命名约定
interface UserInterface {
email:string
name:string
lastName:string
}
接下来我们要做的是使用实用程序类型来简化代码的冗长。
界面更新:2) 实用程序类型
我们实际上会将此接口更改为一种类型,以便轻松使用实用程序类型 Record
.
type UserInterface = Record<"email" | "name" | "lastName", string>;
至于你的组件,你没有在那里提供太多细节,所以我将提供有关设置状态的详细信息。
功能组件:更新状态
确定您需要“订阅”更改的变量或数据非常重要。例如,如果电子邮件和姓名是静态的(永不更改),则无需将它们置于会导致状态变量默认为空字符串的状态:
const [userData, setUserData] = useState("");
如果不是这种情况并且您确实需要更新和管理电子邮件、姓名和姓氏更新状态很简单:使用更新后的值传播现有状态。您可以使用从 useState 返回的元组中提供的 setter 函数来执行此操作。在本例中为 setUserData
。 setter 函数采用与默认 或 相同类型的值,它可以接受回调函数,它为您提供 current 状态值。这对于更新状态对象变量非常强大且非常有用。对于您的情况,我们有:
setUserData((previous) => ({...previous, name: "Updated name value"});
这里发生了什么?如果我们向 setUserData
传递回调,它会为我们提供“先前”状态。第一次调用此函数时,"previous" 是:
{
email: "",
name: "",
lastName: ""
}
我们正在获取该值并将其分布在具有更新值的 new 对象中。这与 Object.assign 相同。如果您传播对象中已存在的键,它将被替换。在我们传播我们的状态对象之后看起来像:
{
email: "", // didn't change because we didn't pass a new value
lastName: "", // didn't change because we didn't pass a new value
name: "Updated name value" // changed because we passed a new value
}
这意味着,如果您想更新电子邮件,只需执行以下操作即可:
setUserData((previous) => ({...previous, email: "hello@world.com"});
现在您的状态对象将是:
{
email: "hello@world.com",
lastName: "",
name: "Updated name value"
}
如果您再次使用回调调用 setUserData
,则之前的值将是上面的那个对象。
如果您想将其设置回原始值,您可以在不使用回调的情况下更新整个状态。为什么?因为我们不需要保留任何值,因为我们想覆盖它:
setUserData({ email: "", lastName: "", name: ""});
虽然有一点改进。如果我们决定在某个时候我们想要“重置为默认值”,我们应该将默认值存储在一个变量中并重新使用它。不是 100% 必要,但它可能是一个很好的更新,特别是如果你有一个复杂的组件。
关于 Typescript 强大功能的快速说明 如果您尝试使用之前未定义的新密钥更新状态,假设“helloWorld”打字稿会给您一个错误,因为“helloWorld”未在您的 UserData 类型中定义。
希望@Jay Lu 的回答和其中的一些信息有所帮助。如果您提供更多详细信息,我们可能会提供更多指导。