React机制总览

React系列195383 阅读0

今天开坑React,本来想看原版文档,奈何英语水平有限。加之最近也许要面试,故先使用中文文档。

本文采用了与vue对照的方式进行对比学习,如果是熟悉vue的人学习起来会更好理解。如果你不了解vue,推荐去看官方文档,也很容易理解:https://zh-hans.react.dev/learn

React组件

按照我的一点印像,react使用js函数return一个html标签,这就是react的组件

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

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

React 组件必须以大写字母开头,而 HTML 标签则必须是小写字母。

export default 关键字指定了文件中的主要组件,这里使用了export default 的MyApp就是我们这个组件文件的入口。

和vue组件的template script style模式不同,react的组件看上去更像是再写js。

使用js夹杂html的语法上被称为 JSX。JSX 比 HTML 更加严格。你必须闭合标签,如 。你的组件也不能返回多个 JSX 标签。你必须将它们包裹到一个共享的父级中,比如 ... 或使用空的 <>...</> 包裹:

样式

在vue和html中添加样式直接使用class="",但是在react中class关键字已经用于定义一个类,所以改成了使用className=""

当然css样式的写法就不如vue方便了,能够直接写在组件的文件里。react只能写在一个单独的.css文件中,当然使用Tailwind CSS会方便很多,挺简单,边学边用就行了。

渲染数据

渲染数据和vue的{{}} 和 :xxx="" 不同。

{{}}改成了 {}

:xxx="" 改成了 xxx={}

官方的说法是:JSX 会让你把标签放到 JavaScript 中。而大括号会让你 “回到” JavaScript 中。

条件渲染

react没有v-if、v-show的写法,直接使用js的if来判断就行了,

let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);

或者三元表达式

<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>

也可以

<div>
{isLoggedIn && <AdminPanel />}
</div>

循环渲染

同样也没有v-for="item in xxx"

依赖 JavaScript 的特性,例如 for 循环 和 array 的 map() 函数 来渲染组件列表。例如:

const listItems = list.map(item =>
<li key={item.id}>
{item.title}
</li>
);

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

响应事件

定义好方法后使用onClick={}即可,就像vue的@click

function MyButton() {
function handleClick() {
alert('You clicked me!');
}

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

注意,onClick={handleClick} 的结尾没有小括号!不要 调用 事件处理函数:你只需 把函数传递给事件 即可。当用户点击按钮时 React 会调用你传递的事件处理函数。

错误写法:

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

这表示 你在渲染组件的时候就立即调用了 handleClick 函数,并把它的返回值(这里是 undefined,因为 alert(...) 没有返回值)赋值给 onClick,这会导致两个问题:

  1. 页面加载时立即弹出 alert,不是等用户点击时才弹。
  2. 点击按钮不会再有任何反应,因为 onClick 现在是 undefined。

有人问,不让写括号,那么怎么传参数给handleClick呢?

其实很简单,你可以使用箭头函数包一层:

<button onClick={() => handleClick('参数')}>
点我
</button>

这样写法中:

() => handleClick('参数') 是一个新的匿名函数,

它只在用户点击时才执行 handleClick('参数')。

响应式

即我们在修改某一变量时页面实时重新渲染的机制。

vue2写在data中,vue3使用ref或reactive。而在react中会比较繁琐一点。

import { useState } from 'react';
function MyButton() {
const [count, setCount] = useState(0);
// ...

这样我们就定义了一个响应式变量

使用的时候直接使用count,修改只能通过setCount来修改,不能向vue一样count = "xxx"。

使用 Hook

以 use 开头的函数被称为 Hook。useState 是 React 提供的一个内置 Hook。你可以在 React API 参考 中找到其他内置的 Hook。你也可以通过组合现有的 Hook 来编写属于你自己的 Hook。

Hook 比普通函数更为严格。你只能在你的组件(或其他 Hook)的 顶层 调用 Hook。如果你想在一个条件或循环中使用 useState,请提取一个新的组件并在组件内部使用它。

组件间共享数据

在vue中,子组件使用props来接收父组件传入的参数,使用emit来将数据传递给父组件。

在react由于每个组件都像是js方法,所以接收父组件的参数是直接使用函数的参数来接收:

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>
);
}

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

这里传入了父组件的方法handleClick,所以子组件MyButton中的onClick实际上执行的是父组件的方法。

总结

个人觉得react写起来比vue更酷,写vue组件给我的感觉像是在一张固定好格式的表格上填写。

对于熟悉js的人应该觉得两种框架难度差不多,无非是写法的不同。而对于不熟悉js的人,则vue会更好上手。

评论

发表评论