» React快速入门 » 1. 上手了解 » 1.11 组件间共享数据

组件间共享数据

在前面的示例中,每个 MyButton 都有其独立的计数,当点击每个按钮时,只有被点击的按钮的 count 发生变化。

然而,有时候你需要组件共享数据并保持同步更新。

为了使两个 MyButton 组件显示相同的 count 并一起更新,你需要将状态从单独的按钮“向上”移动到包含它们俩最近的祖宗组件。

在下面的例子中,共同祖宗是 MyApp

sharing_data_parent 图源:https://react.dev/learn

最初,MyAppcount0,传递给了两个子组件。

sharing_data_parent_clicked 图源:https://react.dev/learn

点击后,MyApp 更新其 count1,并将其传递给两个子组件。

现在,当你单击任一按钮时,MyApp 中的 count 将更改,其将更改 MyButton 中的两个计数。以下是如何在代码中实现这一点。

首先,将状态从 MyButton 移到 MyApp

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  // ... we're moving code from here ...
}

然后,从 MyApp 传递状态到每个 MyButton,以及共享的 click 处理函数。你可以使用 JSX 花括号将信息传递给 MyButton,就像前文使用的内置标签(例如 <img>)一样:

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

你通过这种方式传递的信息称为 props。现在,MyApp 组件包含 count 状态和 handleClick 事件处理函数,并将它们作为 props 传递给每个按钮。

最后,更改 MyButton 以读取从其父组件传递的 props:

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

当你点击按钮时,onClick 处理函数将触发。每个按钮的 onClick prop 都被设置为 MyApp 中的 handleClick 函数,因此其中的代码会被执行。 该代码调用 setCount(count + 1),递增 count 状态变量。新的 count 值作为 prop 传递给每个按钮,因此它们都显示新值。这被称为“将状态向上提升”。通过向上移动状态,你已经在组件之间共享了它。

App.js:

import { useState } from 'react';

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

Counters that update together