React生态简介

本文最后更新于 2025年8月25日 晚上

React

React 是一个构建用户界面的库,核心思想是组件化 + 状态驱动视图 + 声明式编程。描述 UI 时应该是什么样子(State -> UI),而不是如何操作 DOM(命令式)。

核心概念

  • 组件 (Component)
    UI 的最小单元,分为函数组件类组件,Hooks 出来后基本用函数组件

  • JSX
    一种语法糖,把 HTML 和 JavaScript 混合书写,编译后变成 React.createElement

  • Props
    组件外部传入的数据(最好只读)

  • State
    组件内部管理的数据(可变)

  • 数据流
    单向数据流:Props DownEvents Up(数据通过 props 向下传递、事件向上触发)

  • Hooks(函数组件核心)

    • useState → 管理组件内部状态
    • useReducer → 适合管理复杂 state 逻辑(是 useState 的替代方案)
    • useEffect → 处理副作用(数据获取、订阅、手动操作 DOM)
    • useContext → 跨组件传递数据,无需组件层层传递,直接读取 Context
    • useMemo / useCallback → 性能优化,缓存函数和计算结果,避免不必要的重渲染
    • useRef → 获取 DOM 节点或存储任何可变值(.current 属性),变化不会引发重渲染

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { useState, useEffect } from "react";

export default function (props) {
const { initialName } = props;
const [name, setName] = useSate(initialName);
const [count, setCount] = useState(0);

useEffect(() => {
document.title = `你点击了 ${count} 次`;
console.log("Count updated:", count);

return () => {
console.log("清理副作用");
};
}, [count]);

const handleClick = () => {
setCount(count + 1);
setName(`New Namw`)e
};

return (
<div>
<h1>Hello, {name}</h1>
<p>Count: {count}</p>
<button onClick={handleClick}>点击增加</button>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { useState, useEffect } from "react";

function Parent() {
const [data, setData] = useState("父组件自身的数据");
const handleChildEvent = (childData) => {
console.log("来自子组件的数据", childData);
setData(childData);
};

return (
<div>
<Child data={data} onEvent={handleChildEvent} />
</div>
);
}

function Child(props) {
const { data, onEvent } = props;
return <button onClick={() => onEvent("子组件自身的数据")}>{data}</button>;
}

Redux

入门 Redux
入门 React Redux

Redux 是 状态管理工具,用来管理复杂应用的全局状态。

核心思想

  • 单一数据源 store:全局状态仓库,唯一
  • 状态不可变 state:存储的数据本身
  • action:一个普通对象,描述“发生了什么”
  • dispatch:发送 action 的唯一方式
  • reducer: 纯函数更新,接收 state + action => 返回新 state

核心概念

当使用普通对象来描述应用的 state 时。例如,todo 应用的 state 可能长这样:

1
2
3
4
5
6
7
const state = {
todos: [
{ text: "Eat food", completed: true },
{ text: "Exercise", completed: false },
],
visibilityFilter: "SHOW_COMPLETED",
};

state 对象就像 “Model”,区别是它没有 setter(修改器方法)。因此其它的代码不能随意修改它,否则会造成难以复现的 bug。

要想更新 state 中的数据,需要发起一个 actionaction 就是一个普通 JavaScript 对象(注意到没,并没有什么魔法?)用来描述发生了什么。下面是一些 action 的示例:

1
2
3
4
5
const actions = [
{ type: "ADD_TODO", text: "Go to swimming pool" },
{ type: "TOGGLE_TODO", index: 1 },
{ type: "SET_VISIBILITY_FILTER", filter: "SHOW_ALL" },
];

强制使用 action 来描述所有变化可以让清晰地知道应用中到底发生了什么。如果一些东西改变了,就可以知道为什么变。actions 就像是描述所发生事情的面包屑导航。最终,开发一个函数将 actionstate 联系起来,这个函数就是 reducer。同样,这也没有使用什么魔法,reducer 只是一个接收 stateaction 作为其参数,并返回应用新 state 的函数。对于大的应用来说,不大可能仅仅只写一个这样的函数,所以编写很多小函数来分别管理 state 的一部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function visibilityFilter(state = 'SHOW_ALL', action) {
if (action.type = 'SET_VISIBILITY_FILTER') {
return action.filter
} else {
return state
}
}

function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([ text: action.text, completed: false ]);
case 'TOGGLE_TODO':
return state.map((todo, index) => {
action.index === index ?
{ text: todo.text, completed: !todo.completed } : todo
})
default:
return state
}
}

再开发一个 reducer,通过调用两个 reducer 来获取相应的状态,进而来管理整个应用 state

1
2
3
4
5
6
function todoApp(state = {}, action) {
return {
todos: todos(state.todos, action),
visibilityFilter: visibilityFilter(state.visibilityFilter, action),
};
}

这差不多就是 Redux 的全部思想。注意,还没有使用任何 Redux 的 API。Redux 里有一些实用的工具来简化这种模式,但是其主要思想是如何根据 action 对象来更新 state,而且 90% 代码都是普通 JavaScript,没用 Redux 本身、Redux API 或任何魔法。

示例代码

旧写法(connect 高阶组件)

1
2
3
4
5
6
7
8
9
10
11
import { connect } from "react-redux";

const Counter = ({ count, dispatch }) => (
<div>
<p>{count}</p>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
</div>
);

const mapStateToProps = (state) => ({ count: state.count });
export default connect(mapStateToProps)(Counter);

现代写法(Hooks API)

1
2
3
4
5
6
7
8
9
10
11
12
13
import { useSelector, useDispatch } from "react-redux";

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

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

Redux Toolkit (RTK)(推荐,简化写法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// 记忆点:
// createSlice -> configureStore -> <Provider> -> useSelector/useDispatch

// 1. 创建 Slice (包含 reducer 和 actions)
import { createSlice, configureStore } from "@reduxjs/toolkit";

const counterSlice = createSlice({
name: "counter",
initialState: { value: 0 },
reducers: {
// 这里不用返回新state,可以直接“修改”!
// 因为 RTK 使用了 Immer,允许这种“可变”写法,但实际生成的是新状态。
incremented: (state) => {
state.value += 1;
},
decremented: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});

// 自动生成 Action creators
export const { incremented, decremented, incrementByAmount } =
counterSlice.actions;

// 2. 创建 Store
const store = configureStore({
reducer: {
counter: counterSlice.reducer,
// 其他 reducer...
},
});

// 3. 在 React 组件中使用:useSelector, useDispatch
import { useSelector, useDispatch } from "react-redux";
import { incremented, decremented, incrementByAmount } from "Slice";

function Counter() {
// 从 store 中提取 counter state
const count = useSelector((state) => state.counter.value);
// 获取 dispatch 函数
const dispatch = useDispatch();

return (
<div>
<span>{count}</span>
{/* dispatch 自动生成的 action */}
<button onClick={() => dispatch(incremented())}>+</button>
<button onClick={() => dispatch(decremented())}>-</button>
<button onClick={() => dispatch(incrementByAmount(5))}>+5</button>
</div>
);
}

// 4. 用 <Provider> 包裹根组件,传入 store
import { Provider } from "react-redux";
import ReactDOM from "react-dom";

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);

Router

React Router 主页

React Router 是用来实现 单页面应用 (SPA) 的前端路由。

基本概念

  • <BrowserRouter>:用 History API 管理路由,包裹整个应用
  • <Routes>/<Route>:定义路由规则,v6 使用相对路径,规则嵌套更直观
  • <Link>:导航链接,替代 <a> 标签
  • useNavigate:替代 useHistory,用于编程式导航
  • useParams:获取 URL 中的动态参数(如 :id)
  • useLocation:获取当前 location 对象信息

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import {
BrowserRouter,
Routes,
Route,
Link,
useParams,
useNavigate,
} from "react-router-dom";

function Home() {
return <h1>Home</h1>;
}

function About() {
return <h1>About</h1>;
}

function User() {
const { id } = useParams();
return <h1>User ID: {id}</h1>;
}

export default function App() {
const navigate = useNavigate();

return (
<BrowserRouter>
<nav>
<Link to="/">Homw</Link>
<Link to="/about">About</Link>
<Link to="/user/42">User 42</Link>
</nav>
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="/about" element={<About />}></Route>
<Route path="/user/:id" element={<User />}></Route>
</Routes>
<button onClick={() => navigate("/about")}>Go to About</button>
</BrowserRouter>
);
}

React生态简介
https://xuekeven.github.io/2025/08/23/React生态简介/
作者
Keven
发布于
2025年8月23日
更新于
2025年8月25日
许可协议