跳到主要内容

React 教程

React 是一个用于构建用户界面的 JavaScript 库,由 Facebook 开发并维护。它采用组件化开发模式,让开发者能够构建可复用的 UI 组件。

什么是 React?

React 是一个声明式、高效且灵活的用于构建用户界面的 JavaScript 库。它让你可以通过组合小组件来构建复杂的 UI。

React 的核心概念

  • 组件化:将 UI 拆分为独立、可复用的组件
  • 虚拟 DOM:提高性能的虚拟 DOM 机制
  • 单向数据流:数据从父组件流向子组件
  • JSX:JavaScript 的语法扩展

快速开始

环境要求

  • Node.js 14.0 或更高版本
  • npm 或 yarn 包管理器

创建 React 应用

使用 Create React App 创建新项目:

npx create-react-app my-app
cd my-app
npm start

手动安装 React

npm install react react-dom

基础语法

第一个组件

import React from "react";

function Welcome(props) {
return <h1>Hello, {props.name}!</h1>;
}

export default Welcome;

类组件

import React, { Component } from "react";

class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}

export default Welcome;

函数组件(推荐)

import React from "react";

const Welcome = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};

export default Welcome;

状态管理

useState Hook

import React, { useState } from "react";

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

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}

useEffect Hook

import React, { useState, useEffect } from "react";

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

useEffect(() => {
document.title = `You clicked ${count} times`;
});

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}

事件处理

function Button() {
const handleClick = (e) => {
e.preventDefault();
console.log("Button clicked!");
};

return <button onClick={handleClick}>Click me</button>;
}

条件渲染

function Greeting({ isLoggedIn }) {
if (isLoggedIn) {
return <h1>Welcome back!</h1>;
}
return <h1>Please sign up.</h1>;
}

列表渲染

function TodoList({ todos }) {
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
}

表单处理

import React, { useState } from "react";

function NameForm() {
const [value, setValue] = useState("");

const handleSubmit = (event) => {
alert("A name was submitted: " + value);
event.preventDefault();
};

return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
</label>
<input type="submit" value="Submit" />
</form>
);
}

组件通信

父子组件通信

// 父组件
function App() {
const [message, setMessage] = useState("Hello from parent");

return (
<div>
<ChildComponent message={message} />
</div>
);
}

// 子组件
function ChildComponent({ message }) {
return <p>{message}</p>;
}

兄弟组件通信

import React, { createContext, useContext, useState } from "react";

const ThemeContext = createContext();

function App() {
const [theme, setTheme] = useState("light");

return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<Header />
<Main />
</ThemeContext.Provider>
);
}

function Header() {
const { theme, setTheme } = useContext(ThemeContext);

return (
<header>
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
Toggle Theme
</button>
</header>
);
}

生命周期

函数组件生命周期

import React, { useEffect } from "react";

function MyComponent() {
useEffect(() => {
// 组件挂载后执行
console.log("Component mounted");

return () => {
// 组件卸载前执行
console.log("Component will unmount");
};
}, []);

useEffect(() => {
// 每次渲染后执行
console.log("Component updated");
});

return <div>My Component</div>;
}

性能优化

React.memo

import React, { memo } from "react";

const MyComponent = memo(({ name }) => {
return <div>{name}</div>;
});

useMemo

import React, { useMemo } from "react";

function ExpensiveComponent({ items }) {
const expensiveValue = useMemo(() => {
return items.reduce((sum, item) => sum + item.value, 0);
}, [items]);

return <div>{expensiveValue}</div>;
}

useCallback

import React, { useCallback, useState } from "react";

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

const handleClick = useCallback(() => {
setCount((c) => c + 1);
}, []);

return <ChildComponent onClick={handleClick} />;
}

路由

React Router 基础

npm install react-router-dom
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";

function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>

<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}

状态管理

Redux 基础

npm install redux react-redux
import { createStore } from "redux";
import { Provider, useSelector, useDispatch } from "react-redux";

// Reducer
const counterReducer = (state = { count: 0 }, action) => {
switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
case "DECREMENT":
return { count: state.count - 1 };
default:
return state;
}
};

// Store
const store = createStore(counterReducer);

// Component
function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();

return (
<div>
<p>{count}</p>
<button onClick={() => dispatch({ type: "INCREMENT" })}>+</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>-</button>
</div>
);
}

function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}

测试

Jest 和 React Testing Library

npm install --save-dev @testing-library/react @testing-library/jest-dom
import { render, screen, fireEvent } from "@testing-library/react";
import Counter from "./Counter";

test("increments counter on button click", () => {
render(<Counter />);
const button = screen.getByText("+");
fireEvent.click(button);
expect(screen.getByText("1")).toBeInTheDocument();
});

部署

构建生产版本

npm run build

部署到 Vercel

npm install -g vercel
vercel

部署到 Netlify

npm install -g netlify-cli
netlify deploy --prod --dir=build

最佳实践

  1. 组件设计:保持组件小而专注
  2. 状态管理:合理使用 useState 和 useEffect
  3. 性能优化:使用 React.memo、useMemo、useCallback
  4. 代码组织:按功能组织文件结构
  5. 类型安全:使用 TypeScript 或 PropTypes

学习资源

常见问题

Q: 什么时候使用类组件还是函数组件?

A: 现在推荐使用函数组件和 Hooks,除非你需要使用一些类组件特有的生命周期方法。

Q: 如何优化 React 应用性能?

A: 使用 React.memo、useMemo、useCallback,避免不必要的重新渲染,合理使用 key 属性。

Q: 如何处理异步操作?

A: 使用 useEffect 处理副作用,结合 async/await 或 Promise 处理异步数据。