React 中巧妙的使用key更新组件

530 阅读2分钟

前言

本文将介绍 子组件根据父组件的传参不同而进行更新 的两种方法,其中使用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 天

点击查看活动详情