组件化开发核心
2025/11/11大约 4 分钟
组件化开发核心
Props 和组件通信
组件之间相互协作,传递信息,共同构建完整的用户界面。实现组件间通信最基础、最核心的机制,就是 Props。
父传子通过 Props 子传父通过事件处理
function App() {
return (
<Hellow
title="hello"
onChange={(count) => {
console.log(count);
}}
/>
);
}interface HellowPropr {
// 父传子
title: string;
render?: (count: number) => React.ReactNode;
// 子传父
onChange?: (count: number) => void;
}
export const Hellow = (props: HellowPropr) => {
const { title, render, onChange } = props;
const [count, setCount] = useState(0);
const handleAdd = () => {
setCount(count + 1);
onChange?.(count + 1);
};
return (
<div>
Hellow {title} --- {count}
<button onClick={handleAdd}>+</button>
{render?.(count)}
</div>
);
};在这里 onChange 就上子组件可以向父组件发送消息的方式。
useContext
useContext 是 React 提供的一个 Hook,用于在组件树中共享状态。它允许我们在组件之间传递数据,而无需通过 props 一级一级地传递。
基本用法
import { useContext } from "react";
// 定义一个 Context
const MyContext = React.createContext(null);
// 父组件提供值
function ParentComponent() {
return (
<MyContext.Provider value={{ name: "shen", age: 25 }}>
<ChildComponent />
</MyContext.Provider>
);
}
// 子组件消费值
function ChildComponent() {
const { name, age } = useContext(MyContext);
return (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
</div>
);
}结合 useState 实现全局状态管理
import { useContext } from "react";
// 定义一个 Context
const MyContext = React.createContext(null);
// 父组件提供值
function ParentComponent() {
const [user, setUser] = useState({ name: "shen", age: 25 });
return (
<MyContext.Provider value={(user, setUser)}>
<ChildComponent />
</MyContext.Provider>
);
}结合 useReducer 实现多重控制状态
import { useContext, useReducer } from "react";
// 定义一个 Context
const MyContext = React.createContext(null);
// 父组件提供值
function ParentComponent() {
const [user, setUser] = useReducer(
(state, action) => {
switch (action.type) {
case "updateName":
return { ...state, name: action.payload };
case "updateAge":
return { ...state, age: action.payload };
default:
return state;
}
},
{ name: "shen", age: 25 }
);
return (
<MyContext.Provider value={(user, setUser)}>
<ChildComponent />
</MyContext.Provider>
);
}状态管理入门 useState
- Props 是从外部传入且不可变的,而 State 则是组件内部自己管理数据,它是可变的。在函数式组件中,我们用来赋予组件状态能力的就上 useState。
- useState 的调用本身非常简单,它接收一个参数作为状态的初始值,然后返回一个包含两个元素的数组。我们通常使用 JavaScript 的数组结构语法来接收这两个值。
当我们调用更新函数时,React 主要会做两件事
- 它会计划一次对状态的更新,将新的状态值保存起来。
- 它会触发该组件的一次重新渲染
在下一次渲染发生时,useState 会返回更新后的最新状态值。真是珍格格“状态更新 -> 触发重新渲染 -> 使用新状态渲染 UI”的循环,构成了 React 动态交互的核心。
import { useState } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
const handleIncrement = () => {
setCount(count + 1);
};
return (
<div>
<p>{count}</p>
<button onClick={handleIncrement}>+</button>
</div>
);
};在使用 useState 时,一个核心原则是状态的不可变性。对于对象或者数组这样的引用类型,我们不应该直接修改他们内部的属性,而是应该总是创建一个新的对象或数组来替换旧的。这是因为 React 通过浅的比较来判断状态是否发生了变化。如果只是修改了原对象的属性,对象的引用地址并未改变,React 可能会认为状态没有变化,从而跳过重新渲染。
错误的做法
import { useState } from "react";
// user 是只读的
const [user, setUser] = useState({ name: "shen", age: 25 });
const handleAgeChange = () => {
user.age = 22;
setUser(user);
};正确的做法
import { useState } from "react";
const [user, setUser] = useState({ name: "shen", age: 25 });
const handleAgeChange = () => {
setUser({ ...user, age: 22 });
};当一个新状态依赖于旧状态
函数式更新。这个函数会接收前一个状态作为参数,并返回新的状态。当新的状态依赖于旧的状态时,使用函数式更新会更安全、更推荐。它可以避免在快速连续的更新中由于闭包导致的状态陈旧的问题。
条件渲染与列表渲染(key)
动态渲染主要分为两种:
- 条件渲染
- 列表渲染
条件渲染
const AuthStatus = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<div>
{isLoggedIn ? <p>Welcome back</p> : <p>Please log in.</p>}
<button onClick={() => setIsLoggedIn(!isLoggedIn)}></button>
</div>
);
};const Mailbox = ({ unreadMessages }) => {
return (
<div>
<h1>hello !</h1>
{unreadMessages.length > 0 && (
<h2>you Have {unreadMessages.length} unread messages</h2>
)}
</div>
);
};列表渲染
const todos = [
{ id: "a1", text: "Learn React" },
{ id: "b2", text: "Build a Project" },
{ id: "c3", text: "" },
];
const TodoList = () => {
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
};key 的重要性
- key 是 React 用来唯一标识列表中每个元素的特殊属性。
- 它帮助 React 高效地更新、渲染和删除列表项,避免性能问题。
- 每个列表项都应该有一个唯一的 key,通常建议使用数据项的 ID 作为 key。
- 如果列表项没有唯一的 ID,可以考虑使用数组索引作为 key,但这不是推荐的做法,因为索引可能会变化。