基础学习
大约 3 分钟
React 基础学习
核心概念
JSX 语法
JSX 是 JavaScript 的语法扩展,允许在 JS 中编写类似 HTML 的结构。
// 基本用法
const element = <h1>Hello, React!</h1>;
// 嵌入表达式
const name = 'React';
const element = <h1>Hello, {name}!</h1>;
// 条件渲染
const element = isLoggedIn ? <UserGreeting /> : <GuestGreeting />;
// 列表渲染
const listItems = items.map(item => <li key={item.id}>{item.name}</li>);组件
函数组件(推荐)
function Welcome({ name }) {
return <h1>Hello, {name}</h1>;
}
// 使用
<Welcome name="React" />类组件
import { Component } from 'react';
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}Props 属性
// 父组件传递
function App() {
return <User name="Alice" age={25} />;
}
// 子组件接收
function User({ name, age }) {
return (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
</div>
);
}
// 默认 Props
function Button({ text = 'Click' }) {
return <button>{text}</button>;
}State 状态
useState Hook
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(prev => prev - 1)}>-1</button>
</div>
);
}对象状态更新
function UserForm() {
const [user, setUser] = useState({ name: '', email: '' });
const updateField = (field, value) => {
setUser(prev => ({ ...prev, [field]: value }));
};
return (
<form>
<input
value={user.name}
onChange={e => updateField('name', e.target.value)}
/>
<input
value={user.email}
onChange={e => updateField('email', e.target.value)}
/>
</form>
);
}生命周期与副作用
useEffect
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
// 组件挂载 + userId 变化时执行
useEffect(() => {
fetchUser(userId);
}, [userId]);
// 仅组件挂载时执行
useEffect(() => {
console.log('Component mounted');
return () => console.log('Component will unmount');
}, []);
// 每次渲染后执行
useEffect(() => {
document.title = user?.name || 'Loading...';
});
async function fetchUser(id) {
setLoading(true);
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
setUser(data);
setLoading(false);
}
if (loading) return <div>Loading...</div>;
return <div>{user.name}</div>;
}事件处理
function Form() {
const [text, setText] = useState('');
// 事件对象
const handleChange = (e) => {
setText(e.target.value);
};
// 阻止默认行为
const handleSubmit = (e) => {
e.preventDefault();
console.log('Submitted:', text);
};
// 传递参数
const handleClick = (id) => {
console.log('Clicked:', id);
};
return (
<form onSubmit={handleSubmit}>
<input value={text} onChange={handleChange} />
<button onClick={() => handleClick(1)}>Click</button>
</form>
);
}表单处理
受控组件
function LoginForm() {
const [formData, setFormData] = useState({
username: '',
password: ''
});
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
};
return (
<form onSubmit={handleSubmit}>
<input
name="username"
value={formData.username}
onChange={e => setFormData(prev => ({
...prev,
username: e.target.value
}))}
/>
<input
type="password"
name="password"
value={formData.password}
onChange={e => setFormData(prev => ({
...prev,
password: e.target.value
}))}
/>
<button type="submit">Login</button>
</form>
);
}组件通信
父子通信
// 父 -> 子:通过 Props
// 子 -> 父:通过回调函数
function Parent() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<Child count={count} onIncrement={() => setCount(c => c + 1)} />
</div>
);
}
function Child({ count, onIncrement }) {
return <button onClick={onIncrement}>Count: {count}</button>;
}Context 跨层级通信
import { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const toggleTheme = () => setTheme(t => t === 'light' ? 'dark' : 'light');
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
function ThemedButton() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<button onClick={toggleTheme}>
Current theme: {theme}
</button>
);
}
// 使用
function App() {
return (
<ThemeProvider>
<ThemedButton />
</ThemeProvider>
);
}常用 Hooks
| Hook | 用途 |
|---|---|
useState | 状态管理 |
useEffect | 副作用处理 |
useContext | 上下文消费 |
useRef | 引用 DOM/持久值 |
useMemo | 缓存计算值 |
useCallback | 缓存函数 |
useReducer | 复杂状态逻辑 |
useRef 示例
import { useRef, useEffect } from 'react';
function TextInput() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
}useMemo & useCallback
import { useMemo, useCallback } from 'react';
function ProductList({ products, filter }) {
// 缓存过滤结果
const filteredProducts = useMemo(() => {
return products.filter(p => p.name.includes(filter));
}, [products, filter]);
// 缓存回调函数
const handleAdd = useCallback((product) => {
addToCart(product);
}, []);
return (
<ul>
{filteredProducts.map(p => (
<ProductItem key={p.id} product={p} onAdd={handleAdd} />
))}
</ul>
);
}性能优化
React.memo
import { memo } from 'react';
const ExpensiveComponent = memo(function ExpensiveComponent({ data }) {
// 仅在 data 变化时重新渲染
return <div>{/* 复杂渲染 */}</div>;
});懒加载
import { lazy, Suspense } from 'react';
const LazyComponent = lazy(() => import('./LazyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}