发布于 2026-01-06 7 阅读
0

绝对新手学习 React,第二部分 DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

零基础入门 React 教程(第二部分)

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

我上一篇关于从零开始学习 React 的随笔博文中,我开始学习ReactJS.org 的教程。我通过复制粘贴代码构建了我的第一个应用程序……但它居然运行成功了!今天,我希望能理解一些我运行的代码。让我们开始吧。


这部分我大概理解了。` React.Component<Component>` 是一个基础组件类,我们创建了一个ShoppingList继承它的类。我猜想组件必须有一个render()方法,该方法返回一些要渲染的 HTML 元素。这里创建了一个<div>带有 ` <header>`className属性的 `<component>` 元素——这和 HTML 的 `<body>` 属性类似吗class ——该元素包含一个头部(`<header>` <h1>)和一个无序列表(`<unordered list> <ul>`),其中列出了 Mark 想要收购的所有公司。

this.props.name我猜,`${{}` 访问的是 `${{} props` 的变量this,我猜它指的是该类的实例ShoppingList。它访问的name是 `${{}`,该变量在示例中类似 XML 的标签中定义。如果可以像这样随意定义属性,那么这种语法就非常酷了。但是,如果我们不将 `${}` 传递给 `${}` 会怎样呢nameShoppingList代码会抛出错误吗?还是会{this.props.name}在应该显示 `${}` 的地方什么都不渲染?

“当我们的数据发生变化时,React 会高效地更新并重新渲染我们的组件。”

原来它是一个响应式编程框架,跟我预想的一样。考虑到它的名字,这也很合理。

“这里的 ShoppingList 是一个React 组件类,或者说React 组件类型。组件接收参数props(称为属性),并通过render方法返回要显示的视图层次结构。”

我的想法也差不多,但我不太明白“视图层级”是什么意思。教程里说,上面那段看起来很像 HTML 的代码也可以这样写:

React.createElement("div", { className: "shopping-list" },
  React.createElement("h1", null, "Shopping List for ", props.name),
  React.createElement("ul", null,
    React.createElement("li", null, "Instagram"),
    React.createElement("li", null, "WhatsApp"),
    React.createElement("li", null, "Oculus")
  )
 );
Enter fullscreen mode Exit fullscreen mode

这让我想起了JavaFX 使用 FXML 和不使用 FXML的区别。使用FXML构建 Java GUI 时,标记更像 XML。而不用 FXML,它看起来更像上面那段代码,其中函数和属性都是通过点.运算符 () 来访问的。

教程中说“ API 参考文档createElement中有更详细的描述”,所以我点击了那个链接,希望能找到一些注释完善的代码:

文档看起来很不错,很容易理解。我猜[props]它是一个属性列表?不过,在上面的代码块中,我们将第二个参数放在了createElement花括号里{className: 'shopping-list'}。但是,当我们把可变参数列表传递[...children]给 `get` 时,它并没有被花括号括起来createElement……我有点困惑。也许有两种类型的列表?一种是列表,另一种是字典(或映射)?

这真是太棒了。这样我们就可以一点一点地用小组件搭建一个应用程序,并在更大的组件中使用这些小组件。下一步是检查我在上一篇文章中复制粘贴的 JavaScript 代码:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {/* TODO */}
      </button>
    );
  }
}

class Board extends React.Component {
  renderSquare(i) {
    return <Square />;
  }

  render() {
    const status = 'Next player: X';

    return (
      <div>
      ...
Enter fullscreen mode Exit fullscreen mode

看起来挺容易理解的。正如教程里提到的,我们有一个Square类,还有一个Board类用来渲染井字棋游戏的九个方格。我猜还有一些代码需要我来写。

没错。下一步是填写两处小细节,我们进行一些更改。

  renderSquare(i) {
    return <Square />;
  }
Enter fullscreen mode Exit fullscreen mode


  renderSquare(i) {
    return <Square value={i} />
  }
Enter fullscreen mode Exit fullscreen mode

和变化

        {/* TO-DO */}
Enter fullscreen mode Exit fullscreen mode


        {this.props.value}
Enter fullscreen mode Exit fullscreen mode

这段代码传递了要在按钮上渲染的正方形的“值”。我修改了这段代码并npm start再次运行。渲染仍然需要很长时间。但它确实有效……

……也算是个好消息。

恭喜!您刚刚成功地将一个属性从父组件 Board 传递给了子组件 Square。在 React 应用中,信息就是通过传递属性(props)从父组件传递到子组件的。

接下来,我们要在 ` in`中添加一个onClick方法,该方法会打开一个 JavaScript窗口。几年前我接触过 JavaScript,以前也遇到过类似的情况,所以对我来说并不难。buttonSquarealert()

接下来,我们将该onClick函数替换为“箭头函数”(在 JavaScript 中它们似乎就是这么叫的)。我认为大多数其他编程语言都称它们为“lambda 函数”:

onClick={function() { alert('click'); }}
Enter fullscreen mode Exit fullscreen mode

……变成……

onClick={() => alert('click')}
Enter fullscreen mode Exit fullscreen mode

这样可以省去一些打字的步骤。教程中特别提到我们需要传递一个函数onClick如果我们只写……

onClick={alert('click')}
Enter fullscreen mode Exit fullscreen mode

那么每次组件重新渲染时都会触发警告。这显然不是我们想要的结果。

接下来,我们给类添加state一个Square属性,让它能够“记住”是否被点击过。这类似于大多数面向对象编程语言中的实例变量/成员变量。看起来我们可以在类定义中的函数state里设置 React 对象的属性:constructor

class Square extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: null
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

这里有两点:

  1. 这个Square类显然调用了父类的构造函数(React.Componentsuper(),并将传递props给父类构造函数。
  2. 教程中“”后面实际上有个逗号null,我猜这是个拼写错误。

在 JavaScript 类中,定义子类的构造函数时必须始终调用 `__init__` super。所有带有 `__init__` 的 React 组件类都constructor应该以 `__init__` 调用开头super(props)

看起来super(props)在任何子类中都是必需的constructor。我想知道它是否必须像 Java 那样,是构造函数的第一行……?上面的摘录对此有点含糊不清。

然后我们通过改变按钮的onClick状态button来改变按钮的属性setState(),这似乎很容易。

onClick={() => alert('click')}
Enter fullscreen mode Exit fullscreen mode

变化

onClick={() => this.setState({value: 'X'})}
Enter fullscreen mode Exit fullscreen mode

当你setState在组件中调用某个函数时,React 会自动更新该组件内部的子组件。

这听起来像是响应式依赖。如果一个对象更新,而其他对象依赖于它,那么这些依赖对象也会被更新。

最后一步是安装React Developer Tools Chrome 扩展程序,这样我就可以在浏览器中检查我的 React 代码了:

好的!


嗯,我确实开始理解 React 的工作原理了。看到像类、构造函数和 lambda 函数这些熟悉的东西,让我更有信心能很快上手。目前为止,我基本上只是做了onClick些功能强大的网页,所以我希望这个框架还能让我做更多的事情。我期待着做出一些很酷的交互式网页!

文章来源:https://dev.to/awwsmm/an-absolute-beginner-learns-react-part-ii-e15