前言
本文将介绍 子组件根据父组件的传参不同而进行更新 的两种方法,其中使用useEffect是大部分人能想到的,其实 用 key prop来更新更加的巧妙,接下来我们就通过一个选择器的例子来看看如何实现
问题
假设我们有一个像这样的 <ModalPopup> 组件。
import React, { useState } from "react";
import { FormComponent } from "./FormComponent";
export function ModalPopup() {
const [selectedUser, setSelectedUser] = useState("");
const users = [
{
id: 1,
name: "小李"
},
{
id: 2,
name: "小张"
}
];
return (
<>
<div>
<select onChange={(e) => setSelectedUser(e.target.value)}>
<option>选择一个用户</option>
{users.map((user) => (
<option key={user.name}>{user.name}</option>
))}
</select>
</div>
<div>
<FormComponent name={selectedUser} />
</div>
</>
);
}
<ModalPopup> 组件是一个用户选择器。选择用户后,我们将 selectedUser 传递给 <FormComponent> 的子组件,这样。
import React, { useState, useEffect } from "react";
export function FormComponent({ name }) {
const [type, setType] = useState(
name === "小李" ? "管理员" : "超级管理员"
);
return (
<>
{name && (
<div>
<br />
<b>{name}</b>
<br />
<b>{type}</b>
</div>
)}
</>
);
}
在这里,在 <FormComponent> 组件中,我们正在渲染我们作为来自 <ModalPopup> 组件的props传入的选定用户的 name 。
除此之外,我们还使用 useState 设置用户的 type 。 值 type 取决于 name 。因此,当我们选择一个用户时, <FormComponent> 组件将渲染所选用户的 name 和 type 。
但是当您选择另一个用户时会出现问题,只有 name 会改变而 type不会 。
为什么?
因为 <FormComponent> 组件的 useState 只会在组件挂载时启动一次。当 name 属性更改时,它不会更新。
使用 useEffect 钩子
为了解决这个问题,我们可以在 <FormComponent> 组件中引入 useEffect 钩子更新内部状态。
useEffect(() => {
setType(name === "小李" ? "管理员" : "超级管理员");
}, [name]);
我们传入 name 作为它对 useEffect 的依赖之一。因此,当更改 name 时,每次选择不同的用户时 type 也会更新。
这样,问题就解决了!
但是有一种更简洁有效的方法来实现!
传入 key prop!
使用 key prop
会立即重置整个组件,
为我们想要重置的组件提供一个唯一的
key属性。组件的内部 state 也会被重置。
因此,前面示例中的 <FormComponent> 组件,可以向它传递一个 key prop。
<FormComponent key={selectedUser} name={selectedUser} />
然后我们可以从 <FormComponent> 组件中完全删除 useEffect ,因为每次选择新用户时都会重置 type 的状态。
import React, { useState } from "react";
export function FormComponent({ name }) {
const [type] = useState(name === "小李" ? "管理员" : "超级管理员");
return (
<>
{name && (
<div>
<br />
<b>{name}</b>
<br />
<b>{type}</b>
</div>
)}
</>
);
}
全文完
谢谢!
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 21 天