redux在react中的基础使用

376 阅读5分钟

安装插件

npm install @reduxjs/toolkit react-redux

reduxjs/toolkitreact-redux 是两个关键的库,它们提供了 Redux 的工具和组件,用于管理应用的状态。下面是它们各自的功能和作用的详细解释:

  1. Redux 工具包 (reduxjs/toolkit):
    • 简化 Redux 设置:它提供了一种简便的方式来创建 Redux store,使得你不需要手动编写 createStorecombineReducers 等函数,同时还能集成开发者工具。
    • 编写 reducer:toolkit 引入了一个名为 createReducer 的函数,它允许你使用一个对象来映射状态更改的逻辑,使得编写 reducer 函数更加直观和高效。
    • 处理 Action:它提供了 createAction 函数,该函数自动创建 action 类型和 action 创建函数,减少代码重复。
    • 处理异步逻辑:toolkit 中的 createAsyncThunk 函数用于创建处理异步操作的 thunk action,可以方便地处理异步请求和中间状态。
    • 管理切片(Slices):库中的 createSlice 函数是一个高级的 reducer 创建函数,它集成了 reducer、actions 和 state 管理,大大简化了 Redux 应用的创建。
  1. React Redux:
    • 连接 React 和 Redux:它提供了一组组件和 API,使得 React 组件可以轻松地连接到 Redux store,订阅 store 中的状态变更。
    • 组件中的状态访问:通过 connect 函数(在函数组件中可以使用 useSelectoruseDispatch hooks),组件可以访问 Redux store 中的状态,并且可以 dispatch action。
    • 高效的渲染:react-redux 确保组件根据 store 中的状态变化高效地渲染,并且提供了性能优化的手段,如 shouldComponentUpdate 或使用 React.memo / React.PureComponent

在实际开发中,reduxjs/toolkit 用于简化 Redux 开发过程中的繁琐操作,提高编码效率和维护性;而 react-redux 则提供了从 React 组件访问和更新 Redux store 的机制,确保组件与 Redux 状态同步更新。两者结合使用,可以构建出高效、可维护的 React 应用。

项目运用

项目中与vue使用类似, 我们会建立一个store文件夹内部用来维护所有的状态管理

store

目录结构

 store
   ├── index.ts
   └── modules
      └── countStore.ts

store 文件夹:该文件夹包含了与 Redux Store 相关的文件。

index.ts:入口文件,用于导入和导出与 Redux Store 配置有关的内容。

modules 文件夹:该文件夹用于组织 Redux 模块,每个模块通常对应着应用中的一个功能领域。

store定义

// 从 reduxjs/toolkit 库中导入 createSlice 函数
import { createSlice } from '@reduxjs/toolkit';

// 使用 createSlice 创建一个名为 count 的切片
const countStore = createSlice({
  // 切片的名称,用于在 Redux DevTools 中识别此切片
  name: 'count',
  // 初始状态,默认为 count: 0
  initialState: {
    count: 10
  },
  reducers: {
    // 定义 increment reducer,用于增加 count 状态值
    increment(state) {
      state.count++;
    },
    // 定义 decrement reducer,用于减少 count 状态值
    decrement(state) {
      state.count--;
    }
  }
});

// 导出 actions,供组件分发
export const { increment, decrement } = countStore.actions;
// 导出默认的 reducer,用于更新 state
export default countStore.reducer;

定义name = count 的状态,并且可以通过分发 incrementdecrement action 来更改这个状态。

组合store

// 导入 Redux Toolkit 提供的 configureStore 函数
import { configureStore } from '@reduxjs/toolkit'; 
// 导入自定义的 countReducer
import countReducer from './modules/countStore'; 

// 使用 configureStore 创建 Redux 存储实例
const store = configureStore({
  // reducer 键值对,指定存储中的 reducer。
  reducer: {
    // 在存储中使用名为 countStore 的键关联 countReducer
    countStore: countReducer,
  },
});

// 导出 configureStore 创建的 Redux 存储实例,以便在应用程序中使用
export default store;

引用

父组件

// 从'react-redux'库导入Provider组件,它允许你将Redux store提供给所有需要它的组件
import { Provider } from 'react-redux'; 
// 导入Redux store实例
import store from './store'; 
// 导入子组件
import Child from './app'; 

export default () => {
  // 从Redux store的状态中解构出countStore对象
  const {countStore} = store.getState();
  
  // 在组件的render方法中,返回要渲染的元素
  return (
    // 使用Provider组件包裹所有内容,让它们都可以访问Redux store
    <Provider store={store}>
      {/* 渲染一个包含根计数器计数信息的div */}
      <div>this is root {countStore.count}
        {/* 渲染子组件 */}
        <Child />
      </div>
    </Provider>
    
  )
}

通过调用Redux store对象的 getState 方法,解构出 countStore 对象。

<Provider> 组件是 react-redux 库提供的一个组件,它允许所有子组件访问Redux store

子组件

// 从'react-redux'库导入useSelector钩子,用于从Redux store中选择和访问状态
import { useSelector } from 'react-redux'

export default () => {
  // 使用useSelector钩子从Redux store中解构出count值,通过指定state => state.countStore来访问countStore状态切片中的count属性
  const { count } = useSelector(state => state.countStore);
  
  return (
    // 使用一个div元素作为容器
    <div>
      {/* 显示一条文本信息 */}
      this is children
      {/* 渲染解构得到的count值 */}
      {count}
    </div>
  )
}

useSelector 是react-redux提供的一个hook, 用来访问外层Provider组件提供的store数据。useSelector 通过编写一个选择器函数来选择 Redux store 中的状态。这个选择器函数会接收整个 store 的 state 作为参数,并应该返回你想要在组件中使用的状态的一部分

修改store

还是上面的示例

// 导入 react-redux 的 useDispatch 和 useSelector 函数,分别用于分发 action 和获取 state
import { useDispatch, useSelector } from 'react-redux'
import { increment, decrement } from './store/modules/countStore'

// 定义 State 接口,用于指定 state 的类型
interface State {
  countStore: {
    count: number
  }
}


export default () => {
  const { count } = useSelector((state: State) => state.countStore)
  // 使用 useDispatch 获取 Redux 的 dispatch 函数
  const dispatch = useDispatch()
  return (
    <div>
      {/* 点击按钮时,分发 decrement 函数来减少计数 */}
      <button onClick={()=> { dispatch(decrement()) }}>-</button>
      {/* 显示当前的计数值 */}
      {count}
      {/* 点击按钮时,分发 increment 函数来增加计数 */}
      <button onClick={() => {dispatch(increment())}}>+</button>
    </div>
  )
}

要修改store,只能通过action来修改, 而执行action,需要通过dispatch来调用
所以总结来就是两步:

  1. 首先获取到修改的action
  2. 通过dispatch调用action来修改

需要传参的话, 只需要在调用action时传递过去即可。