
是什么?
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 都是值得我们去深入学习和探索的领域~。












![[AIGC] Spring中的SPI机制详解](https://img-blog.csdnimg.cn/direct/0a50f4c8f3554d86aa7d91504068b517.png)






