简体   繁体   English

Redux 如何设置初始 state

[英]Redux how to set initial state

I'm working on a project which contains React, Redux and TypeScript.我正在开发一个包含 React、Redux 和 TypeScript 的项目。

I can't figure out how to set the initial state because of the type restrictions of TypeScript.由于 TypeScript 的类型限制,我无法弄清楚如何设置初始 state。 Does someone know how to set the types?有人知道如何设置类型吗?

I've compressed everything in one file for simplicity, and will be divided in to separate files later on.为简单起见,我将所有内容压缩在一个文件中,稍后将分成单独的文件。

state/index.ts状态/index.ts

import { Notes } from '@material-ui/icons'
import { createStore, combineReducers } from 'redux'

// Types
type Note = {
    title: string
    description: string
}

type NoteState = {
    notes: Array<Note>
}

type NoteAction = {
    type: string
    payload: Note
}

type CountState = {
    count: number
}

type CountAction = {
    type: string
    payload: number
}

// Actions
const ADD_NOTE = 'ADD_NOTE'
const addNote: (note: Note) => NoteAction = (n) => ({ type: ADD_NOTE, payload: n })

const INCREMENT = 'INCREMENT'
const increment: (n: number) => CountAction = (n) => ({ type: INCREMENT, payload: n + 1 })

// Reducer
const noteReducer: (s: NoteState, a: NoteAction) => NoteState = (s = { notes: [] }, a) => {
    switch (a.type) {
        case ADD_NOTE:
            return { notes: [...s.notes, a.payload] }
        default:
            return s
    }
}

const countReducer: (s: CountState, a: CountAction) => CountState = (s = { count: 0 }, a) => {
    switch (a.type) {
        case INCREMENT:
            return { count: a.payload }
        default:
            return s
    }
}

const rootReducer = combineReducers({
    notes: noteReducer,
    counter: countReducer,
})

type RootState = ReturnType<typeof rootReducer>

// Store
const state = createStore(rootReducer({ notes: [], counter: 0 }, null))

Error When initializing the state object, the IDE gives the following error:初始化 state object 时出错,IDE 出现以下错误:

No overload matches this call.
  Overload 1 of 2, '(reducer: Reducer<unknown, Action<any>>, enhancer?: StoreEnhancer<unknown, unknown> | undefined): Store<unknown, Action<any>>', gave the following error.
    Argument of type 'CombinedState<{ notes: never; counter: never; }>' is not assignable to parameter of type 'Reducer<unknown, Action<any>>'.
      Type 'CombinedState<{ notes: never; counter: never; }>' provides no match for the signature '(state: unknown, action: Action<any>): unknown'.
  Overload 2 of 2, '(reducer: Reducer<unknown, Action<any>>, preloadedState?: {} | undefined, enhancer?: StoreEnhancer<unknown, {}> | undefined): Store<unknown, Action<any>>', gave the following error.
    Argument of type 'CombinedState<{ notes: never; counter: never; }>' is not assignable to parameter of type 'Reducer<unknown, Action<any>>'.ts(2769)

I need to set the App State in the createStore function.我需要在 createStore function 中设置应用程序 State。 Because later, there will be a function retrieving the App State from local storage and pass it through the createStore method.因为后面会有一个 function 从本地存储中检索 App State 并通过 createStore 方法传递。 But I want to make this work first.但我想先完成这项工作。 Does anyone have experience with Redux + TypeScript?有人对 Redux + TypeScript 有经验吗?

Looks like you put the wrong arguments for createStore function.看起来您为createStore function 输入了错误的 arguments。 It would take rootReducer as the 1st argument, initial state as the 2nd argument but you set the result of the call your rootReducer as the 1st argument.它将rootReducer作为第一个参数,初始 state 作为第二个参数,但是您将调用rootReducer的结果设置为第一个参数。 Just change it right as following:只需将其更改如下:

interface AppState {
  notes: NoteState;
  counter: CountState;
}

const rootReducer = combineReducers<AppState>({
  notes: noteReducer,
  counter: countReducer
});

const state = createStore(rootReducer, {
  notes: { notes: [] },
  counter: {
    count: 0
  }
});

One more thing to notice, the 1st state parameter is likely undefined so you have to set it can be undefined :还有一点需要注意,第一个 state 参数可能未定义,因此您必须将其设置为undefined

const noteReducer: (s: NoteState | undefined, a: NoteAction) => NoteState = (

NOTE: Here is the codesandbox for you to mess around: https://codesandbox.io/s/inspiring-sound-0lh92?file=/src/store.ts:1178-1276注意:这里是代码框供您使用: https://codesandbox.io/s/inspiring-sound-0lh92?file=/src/store.ts:1178-1276

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM