如何使用 typescript、next-redux-wrapper、getServerSideProps?

Boo*_*hoi 4 typescript redux next.js next-redux-wrapper

我想要 JavaScript -> TypeScript!但是,好难啊。

// store.js

import { applyMiddleware, createStore, compose, Store } from "redux";
import createSagaMiddleware, { Task } from "redux-saga";
import { createWrapper } from "next-redux-wrapper";
import { composeWithDevTools } from "redux-devtools-extension";

import reducer from "./reducers";
import rootSaga from "./sagas";

const configureStore = () => {
  const sagaMiddleware = createSagaMiddleware();
  const middlewares = [sagaMiddleware];
  const enhancer =
    process.env.NODE_ENV === "production"
      ? compose(applyMiddleware(...middlewares))
      : composeWithDevTools(applyMiddleware(...middlewares));
  const store = createStore(reducer, enhancer);
  store.sagaTask = sagaMiddleware.run(rootSaga);
  return store;
};

const wrapper = createWrapper(configureStore, {
  debug: process.env.NODE_ENV === "development",
});

export default wrapper;
Run Code Online (Sandbox Code Playgroud)
// reducers/index.ts

import { HYDRATE } from "next-redux-wrapper";
import { AnyAction, combineReducers } from "redux";

import url, { IUrlReducerState } from "./reducer_url";
import user, { IUserReducerState } from "./reducer_user";

export type State = {
  url: IUrlReducerState;
  user: IUserReducerState;
};

const rootReducer = (state: State, action: AnyAction) => {
  switch (action.type) {
    case HYDRATE:
      return action.payload;

    default: {
      const combineReducer = combineReducers({
        url,
        user,
      });
      return combineReducer(state, action);
    }
  }
};
export type RootState = ReturnType<typeof rootReducer>;
export default rootReducer;

Run Code Online (Sandbox Code Playgroud)

reducers/index.ts<- 你就是这样做的吗?我改变了一点。

// pages/index.js

import { END } from "redux-saga";
import wrapper from "../store";

export const getServerSideProps = wrapper.getServerSideProps(
  async (context) => {

    context.store.dispatch({
      type: LOAD_USER_REQUEST,
    });

    context.store.dispatch(END);
    await context.store.sagaTask.toPromise();
  }
);

Run Code Online (Sandbox Code Playgroud)

我看到了官方文档,但我不明白:https://github.com/kirill-konshin/next-redux-wrapper#getserversideprops

这些代码在 JavaScript 中没有问题。但 TypeScript 有一个问题。

Lin*_*ste 7

以下是我看到的问题:

  1. 你会得到一个错误,createStore(reducer, enhancer)因为你的reducer类型不适合(state: State | undefined, action: AnyAction) => State。您必须使您的减速器适合这种类型。现在的问题是你的减速器state不允许undefined

改变

const rootReducer = (state: State, action: AnyAction) => {
Run Code Online (Sandbox Code Playgroud)

const rootReducer = (state: State | undefined, action: AnyAction): State => {
Run Code Online (Sandbox Code Playgroud)
  1. 你会得到一个错误,store.sagaTask = sagaMiddleware.run(rootSaga);因为storeredux 创建的对象没有名为 的属性sagaTask这里还有另外一个讨论。

这是一个基于 next-redux-wrapper 文档的解决方案:

为您的商店定义一个新界面,其中包括任务

export interface SagaStore extends Store<State, AnyAction> {
  sagaTask: Task;
}
Run Code Online (Sandbox Code Playgroud)

代替

store.sagaTask = sagaMiddleware.run(rootSaga);
Run Code Online (Sandbox Code Playgroud)

(store as SagaStore).sagaTask = sagaMiddleware.run(rootSaga);
Run Code Online (Sandbox Code Playgroud)

代替

await context.store.sagaTask.toPromise();
Run Code Online (Sandbox Code Playgroud)

await (context.store as SagaStore).sagaTask.toPromise();
Run Code Online (Sandbox Code Playgroud)