Skip to content

React重拾-基础

因项目需要,重拾React

1. React 基础概念

1.1 React 简介

React 是一个用于构建用户界面的库。React 不是一个框架

——它的应用甚至不局限于 Web 开发,它可以与其他库一起使用以渲染到特定环境。例如,React Native 可用于构建移动应用程序;React 360 可用于构建虚拟现实应用程序……

React 称为“框架”时 = React 与 ReactDOM 结合使用

1.2 React 与 JavaScript 的最大区别在于 JSX

  • JSX 表达式
JSX
const heading = <h1>Mozilla Developer Network</h1>;
  • JSX 方法允许我们将元素彼此嵌套,就像使用 HTML 一样:
JSX
const header = (
  <header>
    <h1>Mozilla Developer Network</h1>
  </header>
);

括号只是用来向你(和你的计算机)表明其中的多行代码属于同一个表达式, 等同于

JSX
const header = <header>
  <h1>Mozilla Developer Network</h1>
</header>;

浏览器是无法读取直接解析 JSX 的。我们的 header 表达式经过( Babel 或 Parcel 之类的工具)编译之后是这样的:

javascript
const header = React.createElement(
  "header",
  null,
  React.createElement("h1", null, "Mozilla Developer Network"),
);

1.3 React 驱动的框架

  • Next.js 的页面路由 是一个全栈的 React 框架。它用途广泛,可让你创建任何规模的 React 应用程序——从大部分的静态博客到复杂的动态应用程序。
shell
npx create-next-app@latest
  • Remix 是一个具有嵌套路由的全栈式 React 框架。它可以把你的应用分成嵌套部分,该嵌套部分可以并行加载数据并响应用户操作进行刷新。
shell
npx create-remix
  • Gatsby 是一个快速的支持 CMS 的网站的 React 框架。其丰富的插件生态系统和 GraphQL 数据层简化了将内容、API 和服务整合到一个网站的过程。
shell
npx create-gatsby
  • Expo 是一个 React 框架,可以让你创建具有真正原生 UI 的应用,包括 Android、iOS,以及 Web 应用。它为 React Native 提供了 SDK,使原生部分更容易使用。
shell
npx create-expo-app

2. 创建函数组件。

React 应用程序是由 组件 组成的, 它拥有自己的逻辑和外观。 React 组件是返回标签的 JavaScript 函数, React 组件必须以大写字母开头

jsx
function MyButton() {
  return (
    <button>我是一个按钮</button>
  );
}

至此,你已经声明了 MyButton,现在把它嵌套到另一个组件中:

jsx
export default function MyApp() {
  return (
    <div>
      <h1>欢迎来到我的应用</h1>
      <MyButton />
    </div>
  );
}

组件也不能返回多个 JSX 标签。你必须将它们包裹到一个共享的父级中, 比如<div>...</div>或使用空的 <>...</> 包裹:

jsx
function AboutPage() {
  return (
    <>
      <h1>关于</h1>
      <p>你好。<br />最近怎么样?</p>
    </>
  );
}

3. 组件显示数据

JSX 会让你把标签放到 JavaScript 中。而大括号会让你 “回到” JavaScript 中,这样你就可以从你的代码中嵌入一些变量并展示给用户。例如,这将显示 user.name:

jsx
return (
  <h1>
    {user.name}
  </h1>
);

你还可以将 JSX 属性 “转义到 JavaScript”,但你必须使用大括号 而非 引号。例如,className="avatar" 是将 "avatar" 字符串传递给 className,作为 CSS 的 class。但 src={user.imageUrl} 会读取 JavaScript 的 user.imageUrl 变量,然后将该值作为 src 属性传递:

jsx
return (
  <img
    className="avatar"
    src={user.imageUrl}
  />
);

4. class 和 style

  • 在 React 中,你可以使用 className 来指定一个 CSS 的 class。它与 HTML 的 class 属性的工作方式相同
jsx
<img className="avatar" />
  • style 语法 style={}
jsx
const user = {
  name: 'Hedy Lamarr',
  imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
  imageSize: 90,
};

export default function Profile() {
  return (
    <>
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Photo of ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }}
      />
    </>
  );
}

5. 条件渲染

  • React 没有特殊的语法来编写条件语句,因此你使用的就是普通的 JavaScript 代码。例如使用 if 语句根据条件引入 JSX:
jsx
let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);
  • 如果你喜欢更为紧凑的代码,可以使用 条件 ? 运算符。与 if 不同的是,它工作于 JSX 内部:
jsx
<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>
  • 当你不需要 else 分支时,你也可以使用更简短的 逻辑 && 语法:
jsx
<div>
  {isLoggedIn && <AdminPanel />}
</div>

6. 渲染列表

例如 for 循环 和 array 的 map() 函数 来渲染组件列表。

key 是必须项

jsx
const products = [
  { title: '卷心菜', isFruit: false, id: 1 },
  { title: '大蒜', isFruit: false, id: 2 },
  { title: '苹果', isFruit: true, id: 3 },
];

export default function ShoppingList() {
  const listItems = products.map(product =>
    <li
      key={product.id}
      style={{
        color: product.isFruit ? 'magenta' : 'darkgreen'
      }}
    >
      {product.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}

7. 事件处理

  • 在 React 中处理用户输入和事件(例如按钮点击)。
jsx
function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      点我
    </button>
  );
}

8. State(状态)

  • 使用 useState Hook 来管理组件状态。

通常你会希望你的组件 “记住” 一些信息并展示出来,比如一个按钮被点击的次数。要做到这一点,你需要在你的组件中添加 state。

首先,从 React 引入 useState:

jsx
import { useState } from 'react';

现在你可以在你的组件中声明一个 state 变量:

jsx
function MyButton() {
  const [count, setCount] = useState(0);
  // ...

你将从 useState 中获得两样东西:当前的 state(count),以及用于更新它的函数(setCount)。你可以给它们起任何名字,但按照惯例会像 [something, setSomething] 这样为它们命名。

第一次显示按钮时,count 的值为 0,因为你把 0 传给了 useState()。当你想改变 state 时,调用 setCount() 并将新的值传递给它。点击该按钮计数器将递增:

jsx
function MyButton() {
  const [count, setCount] = useState(0);

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

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

注意,每个按钮会 “记住” 自己的 count,而不影响其他按钮。

9. 组件如何接收和使用 props

如何共享 count, 使用这种方式传递的信息被称作 prop

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

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

  return (
    <div>
      <h1>共同更新的计数器</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

此时 MyApp 组件包含了 count state 以及 handleClick 事件处理函数,并将它们作为 prop 传递给 了每个按钮。

jsx
function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      点了 {count} 次
    </button>
  );
}

这被称为“状态提升”。通过向上移动 state,我们实现了在组件间共享它。

参考资料

:React 的官方文档非常详细,尤其是对初学者非常友好。

京ICP备2024093538号-1