React是一个JavaScript库,可以让你在几分钟内开发前端代码。它有预构建的方法和函数来执行某些任务。React作为一个库包含了一些复杂的术语,如协调(reconciliation)、状态(state)、属性(props)等。它们实际上是什么意思呢?
在这篇文章中,你将以更简单的方式了解这些被夸大的概念。
组件
组件是可重用代码的小块,返回一个要在网页上渲染的React元素。它是组成网页单个部分的一组代码,如按钮、导航栏、卡片等。它就像一个JavaScript函数,但返回一个渲染的元素。它接受称为"Props"的参数。组件以大写字母命名。
函数组件示例
function Heading(props) {
return <h1>加入我们, {props.name}!</h1>;
}
注意:
推荐使用函数组件而不是基于类的组件。
函数组件通常被称为无状态组件。
JSX
JSX是JavaScript XML的缩写,它允许我们在React中编写HTML。它引入了类似XML的标签和属性来创建React元素。它通过让你在.jsx文件中编写类似HTML的代码,使创建React组件变得容易。JSX使代码可读性更强、更整洁,而不是使用复杂的JavaScript。React DOM使用驼峰式命名属性,如htmlFor、onClick。
JSX示例
<h1 className="head">这是H1!</h1>
现在,TSX是包含JSX语法的TypeScript文件的文件扩展名。使用TSX,你可以编写类型检查的代码,同时使用现有的JSX语法。TypeScript不是一种不同的语言,它只是JavaScript的一个超集,添加了可选的静态类型。
更简单地说,使用TSX文件,你可以同时使用TypeScript和JSX编写React组件。
TSX示例
interface AgeProps {
age: number;
}
const GreetAge = (props: AgeProps) => {
return (
<div>
你好,你 {props.age} 岁了。
</div>
);
};
注意:
JSX文件使用.jsx文件扩展名。
TSX文件使用.tsx文件扩展名。
TypeScript的类型系统有助于在开发早期捕获潜在错误。
Fragments
React中的Fragments允许你从一个组件返回多个元素。它将元素列表分组,而不创建额外的DOM节点。它清理了DOM中所有多余的div。这可以快速渲染UI。
Fragments示例
const App = () => {
return (
<>
<h1>吃</h1>
<button>了解更多</button>
<p>代码很有趣</p>
<button>重复</button>
</>
);
}
注意:
Fragments使代码更整洁、更易读。
它们在内存使用上更高效。
它们不能有CSS样式。
Props
"Props"是React中代表属性的特殊关键字。它用于在组件之间传输数据。数据传输流是单向的,即从父组件到子组件。
Props示例
function Head(props) {
return <p>{props.children}</p>;
}
注意: Props是只读的,这确保了子组件不会操纵来自父组件的值。
State
当用户与组件交互时,组件需要跟踪某些值。例如,当用户点击亮/暗模式主题切换按钮时,它的值会改变(从亮到暗,反之亦然)。组件需要记住主题的当前值。在React中,这种特定于组件的内存被称为state。
State使用useState()钩子定义;稍后会详细介绍。
定义state的示例
const [index, setIndex] = useState(0)
注意: 在顶级组件中定义state总是一个好习惯,这样可以更容易地与其他子组件共享,并确保单一的事实来源。
生命周期方法
生命周期方法是你可以在React类中使用的特殊函数,用于在组件存在的各个阶段执行操作。这些阶段是:
挂载: 当组件首次创建并插入DOM时。
更新: 当组件的props或state发生变化,导致组件重新渲染时。
卸载: 当组件从DOM中移除时。
纯度
在函数式编程中,当给定相同的输入返回相同的输出时,就称为纯度。当输入是决定输出的唯一因素时,该函数被称为纯函数。
在React中,当一个组件对于相同的输入(即props)返回相同的输出时,该组件被称为纯组件。
严格模式
严格模式是React中的一个开发特性,它启用额外的安全功能以提高代码质量。它会显示关于潜在错误和bug的警告。它将警告记录到浏览器的控制台中。
严格模式示例
import { StrictMode } from 'react';
function App() {
return (
<>
<StrictMode>
<Header />
<Sidebar />
<Content />
<Footer />
</StrictMode>
</>
)
}
钩子
React中的钩子允许在不编写类组件的情况下使用state和其他React特性。钩子是提供对React的状态管理、副作用和其他特性访问的函数。
一些常用的钩子: useState, useMemo, useRef等。
钩子示例
import React, { useState } from "react"; // 导入useState钩子
function FavoriteColor() {
const [color, setColor] = useState("red"); // 初始化state和setter函数
return (
<>
<h1>我最喜欢的颜色是 {color}!</h1>
<button
type="button"
onClick={() => setColor("blue")} // 更新state
>蓝色</button>
<button
type="button"
onClick={() => setColor("red")} // 更新state
>红色</button>
<button
type="button"
onClick={() => setColor("yellow")} // 更新state
>黄色</button>
</>
);
}
注意:
钩子只能在React函数组件内部调用。
钩子只能在组件的顶层调用。
钩子不能是条件性的。
Context API
Context API用于在组件树中共享数据(如state、函数),而无需在每一级手动传递props。它通过简化状态管理和直接与将使用它的子组件共享数据来避免"prop钻取"。
createContext()方法用于创建一个context。这个函数返回一个context对象,其中包含两个组件 - Provider和Consumer。
Provider用于包裹你希望context可用的组件树部分。它接受一个必需的value prop,其中包含你想要在其他组件之间共享的数据。
useContext钩子用于访问数据。
Context API示例使用createContext()方法创建一个context。将子组件包裹在Context Provider中,并提供state值。
import { useState, createContext} from "react";
const UserContext = createContext();
function ParentCounter() {
const [count, setCount] = useState(10);
return (
<UserContext.Provider value={count}>
<h1>{`当前计数: ${count}!`}</h1>
<Button />
</UserContext.Provider>
);
}
使用useContext钩子访问count的值。
import { useContext } from "react";
function GrandChildConsumer() {
const count = useContext(UserContext);
return (
<>
<h1>这是GrandChildConsumer</h1>
<h2>{`当前计数: ${count}`}</h2>
</>
);
}
注意: 通常使用useContext钩子而不是Consumer,以获得更好的可读性和简洁性。
列表和键
Key是React中列表项的一种特殊属性。当项目被更新、删除或添加时,它充当每个项目的唯一标识符。
不建议将项目的索引作为Key,因为如果项目重新排序,它将影响预期的行为。
想象一下,在购物车中你添加了10个项目,每个项目都有一个唯一的索引作为Key。现在,你决定从购物车中删除第一个和第五个项目。当项目被删除时,索引将发生变化;第二个项目将成为第一个,第六个项目将成为第五个。
列表和键的示例
const fruits = ["苹果", "香蕉", "橙子"];
function FruitList() {
return (
<ul>
{fruits.map((fruit, index) => (
<li key={index}> {fruit} </li>
))}
</ul>
);
}
注意:
建议使用唯一标识列表中项目的字符串作为Key。
第三方库如UUID提供创建唯一键的功能。
表单: 受控组件和非受控组件
React表单允许比传统HTML表单更好地收集和管理用户输入。这些表单使用组件构建,并将用户输入存储到state中。有两种类型的组件:
受控组件 在受控组件中,表单的状态由组件自身管理。这是在React中管理表单数据的推荐方法。当用户与表单交互时(例如,在输入字段中输入),组件的状态会更新以反映变化。
受控组件示例
function ControlledInput() {
const [name, setName] = useState('');
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<label htmlFor="name">名字: </label>
<input type="text" id="name" value={name} onChange={handleChange} />
<p>你的名字是: {name}</p>
</div>
);
}
非受控组件 非受控组件依赖DOM来管理表单数据。组件不直接控制表单的状态,但可以使用DOM方法(如ref)访问值。
非受控组件示例
function UncontrolledInput() {
const nameRef = useRef(null);
const handleClick = () => {
console.log(nameRef.current.value);
}
return (
<div>
<label htmlFor="name">名字: </label>
<input type="text" id="name" ref={nameRef} />
<button onClick={handleClick}>获取名字</button>
</div>
);
}
注意:
受控组件提供表单验证,因为由于使用state,用户的输入立即反映。
非受控组件无法进行表单验证,因为只有在表单提交后才能访问用户的输入。
React Router
React Router用于导航的介绍
基本设置和使用
示例: 创建路由和在页面间导航
React Router是React中用于路由的标准库。它使React应用中的各种组件之间的导航成为可能。它允许更改浏览器URL并将UI与URL同步。React Router对于创建具有导航功能的单页应用(SPA)很重要。
首先,你需要从终端安装React Router。
安装React Router
# 如果你使用npm
npm install react-router-dom
# 如果你使用yarn
yarn add react-router-dom
React Router示例
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";
import Contact from "./pages/Contact";
import NoPage from "./pages/NoPage";
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="*" element={<NoPage />} />
</Routes>
</BrowserRouter>
);
}
首先将你的内容包裹在中。然后我们定义,在其中引入用于导航的。有path属性,指定页面的URL,以及element属性,指定需要在定义的路径上渲染的组件。
注意:
一个应用可以有多个。
可以嵌套。
react-router-dom还有和组件用于导航。
结论 学习任何编程语言的最好方法是多练习项目。构建小项目并尝试这些概念。
如果你觉得这篇文章有帮助,别忘了继续支持我。在下次之前,点赞、分享和学习。