构建Store

要使用Redux,还是要从构建Store开始。使用Redux Toolkit构建Store的时候可以直接使用configureStore函数。

我们可以像以下示例一样构建一个简单的空白Store。

import { configureStore } from '@reduxjs/toolkit';

export const store = configureStore({
  reducer: {}
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

在上面这个示例中,configureStore函数接受了一个对象作为参数,而这个对象中也只有一个名为reducer的空字段。但实际上configureStore函数所能够接受的配置对象的解构还是比较复杂的。以下是其可以接受的配置对象的类型定义,从这个类型定义可以看出configureStore函数斗能够配置哪些内容。

interface ConfigureStoreOptions<S = any, A extends Action = AnyAction, M extends Middlewares<S> = Middlewares<S>> {
  // reducer属性可以接受一个函数或者一个对象。
  // 当给定的值是一个函数的时候,这个函数的返回结果将直接被作为Store的初始值和结构使用。
  // 或者还可以使用一个由命名的State片段组成的对象作为属性值,此时Store即是这些片段的集合,这也是configreStore常用的配置方法。
  // 给定一个由片段组成的对象的方法将会直接将其传递给combineReducers方法。
  reducer: Reducer<S, A> | ReducersMapObject<S, A>;

  // 用于指定一组用于附加在Store上的中间件。会自动将这里设置的所有中间件都传递给applyMiddleware方法。
  // 如果没有配置,confugreStore将会调用getDefaultMiddleware函数使用默认配置的中间件。
  middleware?: M | ((getDefaultMiddleware: CurrieGetDefaultMiddleware<S>) => M);

  devTools?: boolean | DevToolsOptions;

  // 用于指定一个初始的state,如果设置了,将会传递给createStrore函数使用。
  preloadedState?: DeepPartial<S extends any ? S : S>;

  // 用于为Store指定一组enhancer,或者通过一个生成函数来自定义和生成一组enhancer。
  // 此处定义的enhancer将会被传递给createStore函数使用。
  enhancers?: StoreEnhancer[] | ((defaultEnhancers: StoreEnhancer[]) => StoreEnhancer[]);
}

这个空白的Store在于React应用结合的时候是通过React的Context(上下文)注入的。但是这个上下文的注入不是通过React的Context.Provider,而是直接通过Redux React提供的Provider组件。例如上面的这个空白Store可以如下例一样注入到应用中。

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import './index.css';
import { store } from './store/root_store';

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