react-redux详解---附Redux Toolkit

329 阅读4分钟

当你的 React 应用程序变得越来越复杂时,管理应用程序状态的难度也会随之增加。React-Redux 库为 React 应用程序提供了一个可预测的状态容器,它将应用程序状态存储在一个单一的 store 中,并提供了一种在组件之间共享状态的机制。

React-Redux 是一个基于 Flux 架构的库,它将应用程序状态分为两个部分:state 和 action。state 是应用程序状态的当前值,而 action 是描述如何更改状态的对象。通过将 state 和 action 分离,React-Redux 可以确保应用程序状态的变化是可预测的,并且可以轻松地进行调试和测试。

React-Redux 的核心概念是 store、action 和 reducer。store 是应用程序状态的单一存储库,它包含了所有组件共享的数据。action 是一个纯 JavaScript 对象,描述了如何更改 store 中的数据。reducer 是一个纯函数,接收当前状态和 action,并返回一个新的状态。当 action 被分发到 store 时,store 将当前状态和 action 传递给 reducer,然后将返回的新状态存储在 store 中。

下面是一个简单的示例,演示如何使用 React-Redux 来管理应用程序状态:

首先,安装 React-Redux 库:

复制
npm install react-redux

然后,创建一个 store.js 文件,定义应用程序状态的初始值和 reducer:

const initialState = {
  count: 0
};

function reducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
}

export default reducer;

接下来,在 App.js 文件中创建一个容器组件和两个展示组件:

import React from 'react';
import { connect } from 'react-redux';

function Counter(props) {
  const { count, increment, decrement } = props;
  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

function mapStateToProps(state) {
  return {
    count: state.count
  };
}

function mapDispatchToProps(dispatch) {
  return {
    increment: () => dispatch({ type: 'INCREMENT' }),
    decrement: () => dispatch({ type: 'DECREMENT' })
  };
}

const ConnectedCounter = connect(
  mapStateToProps,
  mapDispatchToProps
)(Counter);

function App() {
  return (
    <div>
      <ConnectedCounter />
    </div>
  );
}

export default App;

这里的 Counter 组件是一个展示组件,它接收 count、increment 和 decrement 属性,并根据这些属性渲染 UI。mapStateToProps 函数将 store 中的 count 属性映射到 Counter 组件的 props 中,而 mapDispatchToProps 函数将 increment 和 decrement 函数映射到 Counter 组件的 props 中。

最后,在 index.js 文件中创建一个 Provider,将 store 传递给应用程序:

javascript复制
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducer from './store';

import App from './App';

const store = createStore(reducer);

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

这里的 Provider 组件是 React-Redux 库提供的一个高阶组件,它将 store 传递给应用程序,并使所有子组件都可以访问到 store 中的数据。

这就是使用 React-Redux 管理应用程序状态的基本方法。通过将应用程序状态存储在单一的 store 中,并使用 reducer 描述如何更改状态,React-Redux 可以确保应用程序状态变化是可预测的,并且可以轻松地进行调试和测试。

当我们的项目越来越复杂的时候,我们可以考虑Redux Toolkit 可以帮助你更轻松地管理应用程序状态。Redux Toolkit 是一个官方提供的工具包,它提供了一组用于简化 Redux 开发的工具和实用程序。 下面是他的详细使用方法: Redux Toolkit 提供了以下几个主要功能:

  1. configureStore: 一个用于创建 Redux store 的实用程序,它可以自动地合并多个 reducer,并提供了一些其他的默认设置,例如开启严格模式、使用 Redux DevTools 等。
  2. createSlice: 一个用于创建 reducer 和 action 的实用程序,它可以根据指定的初始状态和一组 reducer 函数自动生成 reducer 和 action。
  3. createAsyncThunk: 一个用于处理异步操作的实用程序,它可以自动生成一组异步 action 和对应的 reducer 函数。

下面是一个使用 Redux Toolkit 的示例代码:

javascript复制
import { configureStore, createSlice, createAsyncThunk } from '@reduxjs/toolkit';

// 定义初始状态
const initialState = {
  count: 0,
  status: 'idle',
};

// 定义 incrementAsync 异步操作
const incrementAsync = createAsyncThunk('counter/incrementAsync', async (amount) => {
  await new Promise((resolve) => setTimeout(resolve, 1000));
  return amount;
});

// 创建 counter slice
const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment(state, action) {
      state.count += action.payload;
    },
    decrement(state, action) {
      state.count -= action.payload;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(incrementAsync.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(incrementAsync.fulfilled, (state, action) => {
        state.status = 'idle';
        state.count += action.payload;
      });
  },
});

// 创建 store
const store = configureStore({
  reducer: counterSlice.reducer,
});

// 导出 action 和 reducer
export const { increment, decrement } = counterSlice.actions;
export default store;

在这个示例中,我们使用 createSlice 创建了一个名为 counter 的 slice,并定义了 incrementdecrement 两个 reducer。我们还使用 createAsyncThunk 定义了一个名为 incrementAsync 的异步操作,并在 extraReducers 中处理了异步操作的状态。

最后,我们使用 configureStore 创建了一个 Redux store,并将 counterSlice.reducer 作为参数传递给 reducer。我们还通过 counterSlice.actions 导出了 incrementdecrement action。