如何使用 typescript、next-redux-wrapper、getServerSideProps? [英] how to use typescript, next-redux-wrapper, getServerSideProps?
问题描述
你好,我想要 javascript ->打字稿!但是,太难了..
Hello I want javascript -> typescript! but, so hard..
帮助!!!
// 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;
// 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;
reducers/index.ts <- 你是这样做的吗?我已经改变了一点.
reducers/index.ts <- Is this how you do it? I've changed it a little bit.
// 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();
}
);
看了官方文档,没看懂.[https://github.com/kirill-konshin/next-redux-wrapper#getserversideprops]
I saw the official document, but I don't understand. [https://github.com/kirill-konshin/next-redux-wrapper#getserversideprops]
这些代码在 JavaScript 中没有问题.但是打字稿有问题.
These codes are not problematic in JavaScript. But there's a problem with typescripts.
我英语不好.对不起..
I'm not good at English. Sorry..
所以想要简单的代码,简单的描述.
So want Simple Codes, Simple Description.
谢谢.
推荐答案
以下是我看到的问题:
- 您将在
createStore(reducer, Enhancer)
中收到错误,因为您的reducer
不适合类型(state: State | undefined, action: AnyAction) =>状态
.您必须使您的减速器适合这种类型.现在的问题是您的减速器不允许state
为undefined
.
- You will get an error in
createStore(reducer, enhancer)
because yourreducer
does not fit the type(state: State | undefined, action: AnyAction) => State
. You must make your reducer fit this type. The problem right now is that your reducer does not allow forstate
to beundefined
.
改变
const rootReducer = (state: State, action: AnyAction) => {
到
const rootReducer = (state: State | undefined, action: AnyAction): State => {
- 你会在
store.sagaTask = sagaMiddleware.run(rootSaga);
行上得到一个错误,因为 redux 创建的store
对象没有名为 <代码>传奇任务代码>.此处还有另一个讨论.
- You will get an error on the line
store.sagaTask = sagaMiddleware.run(rootSaga);
because thestore
object created by redux does not have a property calledsagaTask
. There is another discussion about that here.
这是一个基于 next-redux-wrapper 文档的解决方案:
Here is one solution, based on the next-redux-wrapper docs:
为您的商店定义一个包含任务的新界面
define a new interface for your store which includes the task
export interface SagaStore extends Store<State, AnyAction> {
sagaTask: Task;
}
替换
store.sagaTask = sagaMiddleware.run(rootSaga);
与
(store as SagaStore).sagaTask = sagaMiddleware.run(rootSaga);
替换
await context.store.sagaTask.toPromise();
与
await (context.store as SagaStore).sagaTask.toPromise();
这篇关于如何使用 typescript、next-redux-wrapper、getServerSideProps?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!