跳到内容

6

使用 Props 显示数据

到目前为止,如果你要重用你的 <Header /> 组件,它每次都会显示相同的内容。

index.html
function Header() {
  return <h1>Develop. Preview. Ship.</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
      <Header />
    </div>
  );
}

但是,如果你想传递不同的文本,或者你提前不知道信息,因为你正在从外部来源获取数据,该怎么办?

常规 HTML 元素具有属性,你可以使用这些属性传递信息片段,从而更改这些元素的行为。例如,更改 <img> 元素的 src 属性会更改显示的图像。更改 <a> 标签的 href 属性会更改链接的目标。

同样,你可以将信息片段作为属性传递给 React 组件。这些被称为 props。例如,考虑按钮的可能变体

Diagram showing 3 variations of a button component: Primary, Secondary, and Disabled

类似于 JavaScript 函数,你可以设计接受自定义参数(或 props)的组件,这些参数会更改组件的行为或在渲染到屏幕时可见的内容。然后,你可以将这些 props 从父组件传递到子组件。

注意: 在 React 中,数据沿着组件树向下流动。这被称为单向数据流。状态(将在下一章中讨论)可以作为 props 从父组件传递到子组件。

使用 props

在你的 HomePage 组件中,你可以将自定义的 title prop 传递给 Header 组件,就像你传递 HTML 属性一样

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
    </div>
  );
}

Header,作为子组件,可以接受这些 props 作为它的第一个函数参数

index.html
function Header(props) {
  return <h1>Develop. Preview. Ship.</h1>;
}

如果你 console.log() props,你可以看到它是一个具有 title 属性的 对象

index.html
function Header(props) {
  console.log(props); // { title: "React" }
  return <h1>Develop. Preview. Ship.</h1>;
}

由于 props 是一个对象,你可以使用 对象解构 来显式命名函数参数内部的 props 值

index.html
function Header({ title }) {
  console.log(title); // "React"
  return <h1>Develop. Preview. Ship.</h1>;
}

然后你可以用你的 title 变量替换 <h1> 标签的内容。

index.html
function Header({ title }) {
  console.log(title);
  return <h1>title</h1>;
}

如果你在浏览器中打开你的文件,你将看到它显示的是实际的单词 "title"。这是因为 React 认为你打算将一个纯文本字符串渲染到 DOM。

你需要一种方法来告诉 React,这是一个 JavaScript 变量。

在 JSX 中使用变量

要使用 title prop,请添加花括号 {}。这些是特殊的 JSX 语法,允许你在 JSX 标记内直接编写常规 JavaScript。

index.html
function Header({ title }) {
  console.log(title);
  return <h1>{title}</h1>;
}

你可以将花括号视为进入 "JavaScript 领域" 的一种方式,而你原本在 "JSX 领域" 中。你可以在花括号内添加任何 JavaScript 表达式(求值为单个值的表达式)。例如

  1. 使用点表示法的 对象属性
example.js
function Header(props) {
  return <h1>{props.title}</h1>;
}
  1. 一个 模板字面量
example.js
function Header({ title }) {
  return <h1>{`Cool ${title}`}</h1>;
}
  1. 函数的返回值
example.js
function createTitle(title) {
  if (title) {
    return title;
  } else {
    return 'Default title';
  }
}
 
function Header({ title }) {
  return <h1>{createTitle(title)}</h1>;
}
  1. 或者 三元运算符
example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default Title'}</h1>;
}

现在你可以将任何字符串传递给你的 title prop,或者,如果你使用了三元运算符,你甚至可以完全不传递 title prop,因为你已经在你的组件中考虑了默认情况

example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default title'}</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
    </div>
  );
}

你的组件现在接受一个通用的 title prop,你可以在应用程序的不同部分重用它。你所需要做的就是更改 title 字符串

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
      <Header title="A new title" />
    </div>
  );
}

遍历列表

常见的情况是,你需要以列表的形式显示数据。你可以使用数组方法来操作你的数据,并生成样式相同但包含不同信息的 UI 元素。

将以下名称数组添加到你的 HomePage 组件

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

然后你可以使用 array.map() 方法迭代数组,并使用一个箭头函数将名称映射到一个列表项

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

注意你是如何使用花括号在 "JavaScript" 和 "JSX" 领域之间穿梭的。

如果你运行这段代码,React 会给我们一个关于缺少 key prop 的警告。这是因为 React 需要一些东西来唯一标识数组中的项目,以便它知道在 DOM 中更新哪些元素。

你现在可以使用名称,因为它们目前是唯一的,但建议使用一些保证唯一的东西,比如项目 ID。

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
    </div>
  );
}

额外资源

你已完成本章6

你已经学习了如何使用 props 来显示数据。

接下来

7:使用 State 添加交互性

学习如何使用 React 状态和事件监听器添加交互性。