Redux + React-Redux + Redux-Thunk 在 React 实际项目开发中使用详解

本文详细介绍了如何在React项目中使用Redux进行状态管理,包括安装配置、store创建、组件中使用store及触发action,配合react-redux和redux-thunk实现高效状态管理。

React 是我们的视图框架,但在大型项目开发的时候需要公用的数据状态是很难管理的,有明显父子关系的组件还比较方便传递值,但没关系的组件传值是非常麻烦的,这时候就需要用到我们的状态管理库 Redux,该文章会讲解在实际React项目开发中redux + react-redux + redux-thunk 组合应用,这也是我们现在企业项目开发中最常用的搭配,让你能够快速应用起来!

一、Redux 介绍

Redux 是搭配 React 项目开发中最常用的状态管理库,大家知道在我们 React项目开发时,组件的公用数据状态(如用户信息等),可能多组件都会用到,如果组件间的关系比较明确(如父子关系),传递还比较方便,但如果关系不明确或者毫无关系,这时候就非常麻烦了,但借助我们的Redux可以把这些状态存到Reduxstore中,哪个组件需要就去store里面取,哪个组件想要改变store,就去调取相应的actionaction会触发reducer改变store,这样每个组件的store都会改变。

二、Redux 安装

npm i redux react-redux redux-thunk

这里我们一次安装了三个库:

redux:核心库,完成store数据状态管理,reducer(触发会返回新的store替换老的store)管理,action(reducer我们不能直接触发,需要调用action来触发reducer)管理。

react-redux:用来简化在React中使用Redux的流程,其中Provider提供器,全局提供store状态,connect连接器,需要store状态的用他来连接。

redux-thunk:使reduxaction能够写异步方法,本身action中是不能写异步方法的,用了redux-thunk才可以。

三、创建store相应文件(store、reducer、action、action-type)

在项目src目录中创建相应目录和文件
在这里插入图片描述
store/index.js:创建store,并把reducer传入作为第一个参数,应用中间件redux-thunk作为第二个参数,具体代码如下

import { createStore, applyMiddleware } from "redux";
import reducer from "./reducer";
import thunk from "redux-thunk";

const store = createStore(reducer, applyMiddleware(thunk));

export default store;

store/reducer.js:创建了一个countreducer,每次触发action的时候会把传过来的值作为第二个参数,第一个参数为老的statereducer执行完毕返回新的state会替换老的state,其中我们还引入reduxcombineReducers是用来合并多个reducer最终返回一个集成的reducer

import { combineReducers } from "redux";
import { COUNT_ADD, COUNT_REDUCE } from "./action-type";

const initCount = {
  count: 0,
};

function count(state = initCount, action) {
  switch (action.type) {
    case COUNT_ADD:
      return state.count + 1;
    case COUNT_REDUCE:
      return state.count - 1;
    default:
      return state;
  }
}

export default combineReducers({
  count,
});

store/action.js:每次我们想要改变store,都需要先触发action,另外我们用了redux-thunk后。可以在action中执行异步方法(如ajax数据请求等),action去触发reducer发生store的改变。在此示例中,我的action比较简单,实际中大家的可能比较复杂,但是原理相同,一个action方法,执行相应逻辑(如ajax请求,或逻辑判断等),最后返回一个action对象,reducer会根据action对象的typedata来执行相应的store更改

import { COUNT_ADD, COUNT_REDUCE } from "./action-type";

export const receiveCountAdd = () => ({ type: COUNT_ADD });

export const receiveCountReduce = () => ({ type: COUNT_REDUCE });

store/action-type.js:这里面是我们相应action对象的type,为什么我要做这么一个步骤,因为我们需要在action.js传递action对象的时候加上他,也要在reducer.js判断相应的type,避免因为type比较长比较复杂,两边不一致,程序也不会报错(因为reducer判断没有相应type就会走default),所以我们设置一个常量作为type

// count自增
export const COUNT_ADD = 'COUNT_ADD'

// count自减
export const COUNT_REDUCE = 'COUNT_REDUCE'

到此我们相应的store就整体创建完毕,接下来就是在相应组件中使用它了。

四、组件中接收store及触发action改变store

在此之前我们要在全局用react-reduxProvider全局提供store状态,这里我们直接在index.js中使用它,并把store传递给他的属性store

import React from "react";
import ReactDOM from "react-dom";
import App from "./views/App";
import { Provider } from "react-redux";
import store from './store'

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

接下来我们就可以在组件中使用connect连接器获取我们需要的store以及相应的action了,首先引入connect和我们创建的相应actionreceiveCountAdd,在暴露组件的使用connect,它是一个高阶函数(执行函数返回一个函数),执行第一个函数时有两个参数(第一个为需要接收的state,这里我们是count,第二个为action,这里用的es6写法),第二个函数再传入我们的组件名,做此步骤后,我们需要的storeaction就会挂载到我们的props上,然后我们获取或者执行就非常简单了(见useEffect中)

import React, { useEffect } from "react";
import { connect } from "react-redux";
import { receiveCountAdd } from "../../store/action";

function Article(props) {
  useEffect(() => {
    props.receiveCountAdd();
    console.log(props.count);
  }, []);
  return <div>文章信息</div>;
}

export default connect(
  (state) => ({ count: state.count }),
  { receiveCountAdd },
)(Article);

至此,Redux + React-Redux + Redux-Thunk 在 React 实际项目开发中使用详解就讲解完毕了,如果有不太明白的小伙伴,可以留言哦!

<think> 我们参考上述引用,结合用户需求(使用React、TypeScript、Reduxreact-router-dom创建项目并进行初始化配置)来给出详细步骤。 注意:引用中提到了不同版本(如react-router-dom有5.2.0和6.x),我们这里以较新且常见的版本为例,但会注意版本差异。 步骤概览: 1. 创建React + TypeScript项目 2. 安装Redux相关依赖(包括reduxreact-redux、@reduxjs/toolkit等) 3. 安装react-router-dom 4. 配置Redux Store(包括创建store、slice等) 5. 配置react-router-dom(路由设置) 6.Redux和Router集成到项目中(使用Provider和Router组件包裹应用) 7. (可选)配置持久化存储(如redux-persist) 详细步骤: 1. 创建React + TypeScript项目 使用Create React App,并指定TypeScript模板: ```bash npx create-react-app my-app --template typescript cd my-app ``` 2. 安装Redux相关依赖 根据引用[3],使用Redux Toolkit(官方推荐)和react-redux: ```bash npm install @reduxjs/toolkit react-redux ``` 3. 安装react-router-dom 根据引用[2]和[3],注意版本差异。这里我们安装react-router-dom v6(最新稳定版): ```bash npm install react-router-dom@6 ``` 同时安装类型声明(TypeScript项目需要): ```bash npm install --save-dev @types/react-router-dom ``` 4. 配置Redux Store 在src目录下创建store文件夹,并创建index.ts文件: ```ts // src/store/index.ts import { configureStore } from '@reduxjs/toolkit'; // 这里假设我们有一个counterReducer,实际中替换成你自己的reducer import counterReducer from './features/counterSlice'; export const store = configureStore({ reducer: { counter: counterReducer, // 其他reducer }, }); // 导出RootState和AppDispatch类型,以便在组件中使用 export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch; ``` 创建slice(示例): ```ts // src/store/features/counterSlice.ts import { createSlice } from '@reduxjs/toolkit'; export const counterSlice = createSlice({ name: 'counter', initialState: { value: 0, }, reducers: { increment: (state) => { state.value += 1; }, decrement: (state) => { state.value -= 1; }, }, }); export const { increment, decrement } = counterSlice.actions; export default counterSlice.reducer; ``` 5. 配置react-router-dom 在src目录下创建路由配置文件,例如src/routes.tsx(或直接写在App.tsx中,但建议分离): ```tsx // src/routes.tsx import { Routes, Route } from 'react-router-dom'; import HomePage from './pages/Home'; import AboutPage from './pages/About'; const AppRoutes = () => ( <Routes> <Route path="/" element={<HomePage />} /> <Route path="/about" element={<AboutPage />} /> </Routes> ); export default AppRoutes; ``` 创建页面组件(例如Home和About)在src/pages目录下。 6. 集成Redux和Router到项目中 修改src/index.tsx,使用Provider提供store,使用BrowserRouter提供路由: ```tsx // src/index.tsx import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import { store } from './store'; import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <React.StrictMode> <Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider> </React.StrictMode> ); ``` 在App.tsx中引入路由: ```tsx // src/App.tsx import AppRoutes from './routes'; function App() { return ( <div className="App"> <AppRoutes /> </div> ); } export default App; ``` 7. (可选)配置持久化存储 如果希望Redux状态持久化(如引用[3]中的redux-persist),可以安装并配置: ```bash npm install redux-persist ``` 修改store配置(src/store/index.ts): ```ts import { configureStore } from '@reduxjs/toolkit'; import { persistStore, persistReducer } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; // 默认使用localStorage import counterReducer from './features/counterSlice'; const persistConfig = { key: 'root', storage, // 可以选择哪些reducer需要持久化 whitelist: ['counter'] }; const persistedReducer = persistReducer(persistConfig, counterReducer); export const store = configureStore({ reducer: { counter: persistedReducer, // 替换原来的counterReducer // 其他reducer }, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false, // 避免持久化相关的序列化检查警告 }), }); export const persistor = persistStore(store); ``` 然后修改index.tsx,添加PersistGate组件: ```tsx import { persistor } from './store'; import { PersistGate } from 'redux-persist/integration/react'; root.render( <React.StrictMode> <Provider store={store}> <PersistGate loading={null} persistor={persistor}> <BrowserRouter> <App /> </BrowserRouter> </PersistGate> </Provider> </React.StrictMode> ); ``` 注意:以上步骤是一个基本配置,实际项目中可能需要根据需求调整。 相关问题: 1. 如何在不同React Router版本中配置路由? 2. Redux Toolkit相比传统Redux有什么优势? 3. 如何优化Redux持久化存储的性能? </think> 以下是使用 React、TypeScript、Reduxreact-router-dom 创建项目并进行初始化配置的详细步骤: ### 一、创建项目基础结构 1. **创建 React+TypeScript 项目** ```bash npx create-react-app my-app --template typescript cd my-app ``` 2. **安装核心依赖** ```bash npm install react-router-dom @types/react-router-dom redux react-redux @reduxjs/toolkit redux-thunk ``` ### 二、Redux 配置 1. **创建 store 结构** ```markdown src/ ├── store/ │ ├── index.ts # Store 主文件 │ └── features/ # Redux 切片目录 │ └── counterSlice.ts ``` 2. **配置 Store (src/store/index.ts)** ```ts import { configureStore } from '@reduxjs/toolkit'; import counterReducer from './features/counterSlice'; export const store = configureStore({ reducer: { counter: counterReducer, // 添加其他 reducer }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(/* 自定义中间件 */), }); export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch; ``` 3. **创建示例 Slice (src/store/features/counterSlice.ts)** ```ts import { createSlice, PayloadAction } from '@reduxjs/toolkit'; interface CounterState { value: number; } const initialState: CounterState = { value: 0 }; const counterSlice = createSlice({ name: 'counter', initialState, reducers: { increment: (state) => { state.value += 1; }, decrement: (state) => { state.value -= 1; }, incrementByAmount: (state, action: PayloadAction<number>) => { state.value += action.payload; }, }, }); export const { increment, decrement, incrementByAmount } = counterSlice.actions; export default counterSlice.reducer; ``` ### 三、路由配置 1. **创建路由文件 (src/AppRouter.tsx)** ```tsx import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import HomePage from './pages/Home'; import AboutPage from './pages/About'; import Layout from './components/Layout'; const AppRouter = () => ( <Router> <Routes> <Route path="/" element={<Layout />}> <Route index element={<HomePage />} /> <Route path="about" element={<AboutPage />} /> <Route path="*" element={<div>404 Not Found</div>} /> </Route> </Routes> </Router> ); export default AppRouter; ``` 2. **创建页面组件 (示例: src/pages/Home.tsx)** ```tsx import { useAppSelector } from '../store'; const HomePage = () => { const count = useAppSelector(state => state.counter.value); return ( <div> <h1>Home Page</h1> <p>Current count: {count}</p> </div> ); }; export default HomePage; ``` ### 四、集成到应用入口 **修改 src/index.tsx** ```tsx import React from 'react'; import ReactDOM from 'react-dom/client'; import { Provider } from 'react-redux'; import AppRouter from './AppRouter'; import { store } from './store'; import './index.css'; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <React.StrictMode> <Provider store={store}> <AppRouter /> </Provider> </React.StrictMode> ); ``` ### 五、补充配置 1. **TypeScript 类型增强 (src/types.d.ts)** ```ts import { RootState, AppDispatch } from './store'; declare module 'react-redux' { interface DefaultRootState extends RootState {} export const useDispatch: () => AppDispatch; } ``` 2. **路由布局组件 (src/components/Layout.tsx)** ```tsx import { Outlet, Link } from 'react-router-dom'; const Layout = () => ( <div> <nav> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/about">About</Link></li> </ul> </nav> <hr /> <Outlet /> {/* 子路由渲染位置 */} </div> ); export default Layout; ``` ### 六、运行项目 ```bash npm start ``` ### 关键配置说明 1. **Redux 优化**:使用 Redux Toolkit 简化 store 配置,自动整合 Thunk 中间件 2. **类型安全**:通过 `RootState` 和 `AppDispatch` 类型确保类型安全 3. **路由嵌套**:使用 `<Outlet>` 实现布局组件嵌套路由 4. **模块化结构**:分离 store/features 实现功能模块化 [^1]: 此配置方案基于 react-router-dom v6Redux Toolkit 最佳实践,支持动态路由加载和状态持久化扩展 [^2]: 类型声明增强确保组件内 `useSelector` 和 `useDispatch` 的类型安全 [^3]: 路由配置采用嵌套布局模式,便于扩展复杂路由结构
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值