当前位置: 首页 > news >正文

React 18.2中使用Redux 5.0.1

 在 React 18 中使用 Redux 5(不使用 Redux Toolkit)需要手动设置 store、reducer、action 等核心概念。以下是具体步骤和示例:

1. 安装必要依赖

首先需要安装 Redux 核心库和 React-Redux 绑定库:

npm install redux@5 react-redux@9
# 或
yarn add redux@5 react-redux@9

2. 创建 Redux Store

创建一个 store,包含 reducer 和初始状态:

store.js

// store.js
import { createStore } from 'redux';// 初始状态
const initialState = {count: 0,todos: []
};// 定义Reducer - 根据不同 action 类型处理状态
function rootReducer(state = initialState, action) {switch (action.type) {case 'INCREMENT':return { ...state, count: state.count + 1 };case 'DECREMENT':return { ...state, count: state.count - 1 };case 'ADD_TODO':return {...state,todos: [...state.todos, action.payload]};default:return state;}
}// 创建 store
const store = createStore(rootReducer);export default store;

actions.js

// actions.js
// Action 创建函数 - 返回 action 对象
export const increment = () => ({type: 'INCREMENT'
});export const decrement = () => ({type: 'DECREMENT'
});export const addTodo = (text) => ({type: 'ADD_TODO',payload: text
});

将 Redux Store 提供给 React 应用,在 React 18 中,通常你会在 index.js或 main.jsx中使用 <Provider>包裹你的根组件(比如 <App />)。

index.jsx

// index.jsx - React 18 入口文件
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';// React 18 新的渲染方式
const root = createRoot(document.getElementById('root'));
root.render(<Provider store={store}><App /></Provider>
);

在 React 组件中使用 Redux State 和 Dispatch:

App.jsx

// App.jsx
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, addTodo } from './actions';function App() {// 从 store 中获取状态const { count, todos } = useSelector((state) => state);// 获取 dispatch 函数const dispatch = useDispatch();return (<div><h1>Count: {count}</h1><button onClick={() => dispatch(increment())}>+</button><button onClick={() => dispatch(decrement())}>-</button><div><h2>Todos</h2><input type="text" ref={(input) => window.todoInput = input} placeholder="Add todo"/><button onClick={() => {dispatch(addTodo(window.todoInput.value));window.todoInput.value = '';}}>Add</button><ul>{todos.map((todo, index) => (<li key={index}>{todo}</li>))}</ul></div></div>);
}export default App;

假如你有多个reducer,你需要使用 combineReducers:

// src/reducers/index.js
import { combineReducers } from 'redux';
import counterReducer from './counterReducer';const rootReducer = combineReducers({counter: counterReducer,// 其他reducers...
});export default rootReducer;
// counterReducer.js
import { INCREMENT, DECREMENT } from './types';const initialState = {count: 0,
};const 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;}
};export default counterReducer;

核心概念说明

Store:

  • 使用 createStore 创建,接收 reducer 作为参数
  • 整个应用只有一个 store

Reducer:

  • 纯函数,接收 state 和 action 并返回新的状态
  • 必须遵循不可变性原则(使用展开运算符 ... 创建新对象)

Action:

  • 普通 JavaScript 对象,必须有 type 属性
  • 通过 action 创建函数生成,便于复用

在 React 中使用:

  • Provider 组件:将 store 提供给整个应用
  • useSelector:从 store 中获取状态(替代了旧版的 mapStateToProps)
  • useDispatch:获取 dispatch 函数,用于分发 action

注意事项

  • Redux 5 和 React-Redux 9 支持 React 18 的并发特性
  • 没有使用 Redux Toolkit 时,需要手动处理不可变性
  • 对于复杂应用,建议拆分 reducer(使用 combineReducers)
  • 异步操作需要额外使用 redux-thunk 等中间件

3、处理异步 Action(使用 redux-thunk)

安装 redux-thunk:

npm install redux-thunk

假如你想实现一个异步的 action,比如从 API 获取数据,你可以这样写:

// asyncActions.js
export const fetchData = () => {return async (dispatch) => {dispatch({ type: 'FETCH_START' });try {const response = await fetch('https://api.example.com/data');const data = await response.json();dispatch({ type: 'FETCH_SUCCESS', payload: data });} catch (error) {dispatch({ type: 'FETCH_FAILURE', payload: error.message });}};
};

然后你需要在 reducer 中处理这些新的 action types。

补充建议

虽然原生 Redux 可用,但 ​​Redux Toolkit(RTK)​​ 是官方推荐的更现代、更简洁的 Redux 开发方式,它封装了最佳实践,大大减少了模板代码。如果你可以接受使用 RTK,建议优先考虑它。

http://www.dtcms.com/a/389813.html

相关文章:

  • 程序开发的基本规律
  • Day26_【深度学习(6)_神经网络NN(1.1)激活函数_softmax详解篇】
  • 通过调用deepseek大模型接口对千条评论信息进行文本分析/词频分析/情感分析
  • 攻坚家电代工转型痛点|远望电器牵手盘古信息,以IMS重塑数字制造根基
  • SpringBoot实现Markdown语法转HTML标签
  • DeepSeek:大语言模型在中文生态中的技术突破与应用探索
  • 【Agent博客分享】从多Agent问题到新的上下文工程方法
  • 点云分割中 offset 与 batch 表示的转换详解
  • C++23 堆栈跟踪功能实战:从内存泄漏梦魇到一键定位的调试革命
  • jvm参数调优(持续更新)
  • 容器查看日志工具-stern
  • 衍射光学元件DOE:台阶高度与位置误差的测量
  • Java中对象/嵌套对象属性复制工具类使用示例:Hutools工具类BeanUtils使用示例
  • rust编写web服务02-路由与请求处理
  • Spring Cloud - 微服务限流的方式
  • 【智能系统项目开发与学习记录】ROS2基础(1)
  • 人工智能面试题:什么是CRF条件随机场
  • [x-cmd] 命令式交互、CLI/TUI 设计与 LLM
  • 基于AMBA总线协议的Verilog语言模型实现
  • 【Agent项目复现】OpenManus复现
  • 高校AI虚拟仿真实训平台软件解决方案
  • Vue3 + Ant Design Vue 实现统一禁用样式管理方案,禁用状态下已有值颜色区分(CSS 变量方案)
  • Ubuntu 24.04部署MongoDB
  • 8.1-spring 事务-声明式事务(使用)
  • Vue3》》组件继承 extends
  • 无人系统在边境管控的应用探讨
  • 一个典型的mysql数据库连接池初始化函数
  • novel英文单词学习
  • 数据结构:树及二叉树--堆(下)
  • TDengine 聚合函数 STDDEV 用户手册