是什么?
Redux 是一个使用叫做 “action” 的事件来管理和更新应用状态的模式和工具库
- 提供全局状态数据的单一仓库(对象树),管理应用的
全局状态
- 单一数据源,状态只读,状态修改
只由纯函数完成
为什么用(特点)?
适用场景:
多组件共用
同一个 state 状态- 更新 state 的逻辑
复杂度高
- 很
多人协同开发
,中型及以上的项目
常用的包:
Redux 常用涉及的包,主要是 Redux
、 Redux-Toolkit
、React-Redux
、Redux-Thunk
,以及调试工具 Redux-Devtools-Extension
。
- Redux:Redux 的
核心包
。它提供了创建 store、统一管理 reducer、绑定 action、中间件集成及管理等组件。 - Redux-Toolkit:Redux 的
工具包
。提供一系列简单易用的 API 和工具,简化 Redux 的开发和代码质量。 - React-Redux:是 Redux 的官方 React
绑定库
。其目的是让 React 组件能够使用 Redux 状态管理。 - Redux-Thunk:
中间件
,用于处理异步操作。使 dispatch 可以接受函数,赋予其执行异步操作的能力。 - Redux-Devtools-Extension:Redux 的
调试工具
。可以显示 Redux 存储中状态随时间变化的历史记录
三大核心概念
- Action: 动作对象,包含两个属性。是改变 state 的唯一方法
- type:必填,唯一性,
String
类型,标识属性 - data:可选,放数据用的。
- 举例:
{ type: 'TOGGLE_TODO', index: 1 }
- type:必填,唯一性,
- Reducer:用于初始化状态、加工状态的纯函数。加工时,根据当前的 state 和 action,产生新的 state。
- Store: 将 state、action、reducer 联系在一起的对象。可以将Store理解为全局的一个变量,且全局只有一个Store。
怎么用?
在 React 项目里面使用 Redux,必不可少要先安装 Redux
和 React-Redux
npm install redux
npm install react-redux
Redux 基本使用
使用 Redux 的核心 createStore
进行状态管理,这是最基本的方法。
现已被官方标记弃用,原因是Redux 4.2以后鼓励用户用户使用 Redux-Toolkit
。
但这并不影响我们对于它的了解,以及如何使用。
我们来举个例子,加减数字的功能
1. 首先,我们先建立一个 counter 的 reducer
// src/reducer/counter.js
const initialState = {
count: 0,
};
export default function counterReducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return {
...state,
count: state.count + 1,
};
case 'DECREMENT':
return {
...state,
count: state.count - 1,
};
default:
return state;
}
}
2. 可创建多个 reducer,通过 combineReducers 方法集成一个 rootReducer
// src/reducer/index.js
import { combineReducers } from 'redux';
import counterReducer from './counter';
export default combineReducers({
counter: counterReducer,
// ... 其他 reducer
});
3. 导入 rootReducer,再由 createStore 创建 store
// src/store/index.js
import { createStore } from 'redux';
import rootReducer from '../reducer';
const store = createStore(rootReducer)
export default store;
4. 最后在应用中集成 Redux Store
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
5. 组件里使用
在上述,状态仓库通过 createStore
,已经创建完毕。创建完了,我们就该去使用这个 store
了。
在这一小节,我们将通过 React-Redux ,useSelector
取值,useDispatch
发出动作去修改值,从而实现这个加减功能。
// src/App.jsx
import { useSelector, useDispatch } from 'react-redux';
function App() {
const { count } = useSelector((state) => state.counter)
const dispatch = useDispatch();
return (
<div className="App">
<p>Count: { count }</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
</div>
);
}
export default App;
有没有觉得用一个全局状态变量,就得这么多步骤,太恶心了吧
这正是官方后续出了 Redux-Toolkit 的原因,那下面我们就用它
Redux-Toolkit 使用
首先,你需要安装它:
npm install @reduxjs/toolkit
1. createSlice 创建 reducer
还是一样,我们先创建一个名为 count
的 reducer
// src/reducer/count.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
count: 0,
};
const counterSlice = createSlice({
name: "counter",
initialState,
reducers: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
}
}
})
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
2. configureStore 创建 store
configureStore
有添加更多 reducer
的功能并创建 store
,直接省去了合并 rootReducer
的步骤
// src/store/index.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../slice/counter';
const store = configureStore({
reducer: {
counter: counterReducer,
// 可以添加更多的 reducer
},
});
export default store;
3. 应用中集成 Redux Store
和上一种方法一样,使用 React-Redux 的 Provider
组件,让组件能够有状态管理
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
4. 组件里使用
组件里使用,和上一种方法也大差不差,主要是加了 action
的导入
// src/App.jsx
import { useSelector, useDispatch } from 'react-redux';
// 就加了这里
import { increment, decrement } from './reducer/counter';
function App() {
const { count } = useSelector((state) => state.counter)
const dispatch = useDispatch();
return (
<div className="App">
<p>Count: {count}</p>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
</div>
);
}
export default App;
Redux DevTools 调试
我们在上述编写完加减数字的功能后,可以下载 Redux DevTools 进行直观的展示,以加深对 Redux 的理解。
扩展插件,可通过网上应用商店获取,非常方便:
添加完毕后,在 React 页面中,F12 呼出开发调试工具,选 Redux 标签就能看到以下数据:
Redux-Thunk 使用
Redux-Thunk
是一个用于处理 Redux 中异步操作的中间件
。
在 Redux 中,reducers 应该是纯函数,只负责处理同步的状态变更,而 Redux-Thunk 则允许你派发一个返回函数的 action,这个函数可以执行异步操作,比如发起 API 请求,然后在异步操作完成后,再派发一个真正的 action 来更新 Redux 中的状态。
其作用:
- 处理异步操作:通过派发返回函数的 action,你可以执行诸如 API 请求等异步任务,并在任务完成后更新应用状态。
- 控制流:Redux-Thunk 允许你在派发 action 时进行条件判断、流程控制等操作,从而更灵活地处理不同情况下的异步行为。
下面是一个简单的 Redux-Thunk 使用示例:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
// 创建一个Redux store,并应用redux-thunk中间件
const store = createStore(rootReducer, applyMiddleware(thunk));
// 一个异步action创建函数
function fetchPostsRequest() {
return {
type: 'FETCH_POSTS_REQUEST'
};
}
function fetchPostsSuccess(posts) {
return {
type: 'FETCH_POSTS_SUCCESS',
payload: posts
};
}
function fetchPostsError(error) {
return {
type: 'FETCH_POSTS_ERROR',
payload: error
};
}
// 使用redux-thunk,我们可以派发一个返回函数的action
export function fetchPosts() {
return function(dispatch) {
dispatch(fetchPostsRequest());
return fetch('https://api.example.com/posts')
.then(response => response.json())
.then(posts => dispatch(fetchPostsSuccess(posts)))
.catch(error => dispatch(fetchPostsError(error)));
};
}
在这个示例中,fetchPosts
是一个异步 action 创建函数,它返回一个函数。这个函数首先派发一个FETCH_POSTS_REQUEST
action 来指示开始获取帖子,然后发起一个 API 请求。当请求成功时,它派发一个FETCH_POSTS_SUCCESS
action 并带上获取到的帖子数据;如果请求失败,则派发一个FETCH_POSTS_ERROR
action 并带上错误信息。
通过这种方式,你可以将异步逻辑与 Redux 的状态管理结合起来,实现更加健壮和可维护的应用。
结束语
在 React 的复习全攻略中,Redux 无疑是一个不可忽视的篇章。
浅尝 Redux 的全局滋味,我们不仅能领略到其集中式状态管理的魅力,更能感受到它如何助力 React 应用实现数据流的清晰
与可控
。
Redux 的出现,极大地简化
了组件间的通信,让我们的代码更加整洁
、高效
。
掌握 Redux,不仅意味着我们能够更好地驾驭 React 应用的全局状态,更是提升我们开发能力的重要一步。
无论是初学者还是资深开发者,Redux 都是值得我们去深入学习和探索的领域~。