reactjs 带有redux工具包的Nextjs导致类型错误:无法读取未定义的属性(读取"title")

qyyhg6bp  于 2023-02-15  发布在  React
关注(0)|答案(1)|浏览(136)

我试图从redux存储中获取值,但每次都是徒劳的。我使用的是redux toolkitnextjs
我的todoSlice是:

import { createSlice, Draft, PayloadAction } from '@reduxjs/toolkit';

export interface TodoState {
    id: number;
    title: string;
    completed: boolean;
    important: boolean;
  }
  
  /**
   * Default state object with initial values.
   */
  const initialState: TodoState = {
    id: 0,
    title: 'Goto Market',
    completed: false,
    important: true
  } as const;

const todoSlice = createSlice({
    name: 'todos',
    initialState,
    reducers: {
        init : (
            state: Draft<typeof initialState>,
            action: PayloadAction<typeof initialState>
        ) => {
            state.id = action.payload.id;
            state.title = action.payload.title;
        },
    }
})

// A small helper of user state for `useSelector` function.
export const getTodoState = (state: { todos: TodoState }) => state.todos;

// Exports all actions
export const { init } = todoSlice.actions;

export default todoSlice;

我的store.ts是:

import { configureStore } from "@reduxjs/toolkit";
import {
    useDispatch as useDispatchBase,
    useSelector as useSelectorBase,
  } from 'react-redux';
import todoSlice from "./todoSlice";
  
const store = configureStore({
    reducer: {
        todos: todoSlice.reducer
    }
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>;

// Inferred type: { todos: TodoState}
type AppDispatch = typeof store.dispatch;

// Since we use typescript, lets utilize `useDispatch`
export const useDispatch = () => useDispatchBase<AppDispatch>();

// And utilize `useSelector`
export const useSelector = <TSelected = unknown>(
  selector: (state: RootState) => TSelected
): TSelected => useSelectorBase<RootState, TSelected>(selector);

export default store;

最后,当我在我的自定义组件中使用它时:

import { CssBaseline, Divider, Grid, List, Typography } from '@mui/material'
import { Box } from '@mui/system'
import React from 'react'

import { init, getTodoState} from '@/data/todoSlice'
import { useDispatch, useSelector } from 'react-redux'

const TodoContainer = () => {
    
    const dispatch = useDispatch();
    const { todos } = useSelector(getTodoState);

    return (
        <>
            <CssBaseline />
            <Box sx={{ m: 2, p: 2, }}>
                <Grid container spacing={{ xs: 2 }} columns={{ xs: 6, sm: 6, md: 12 }}>
                    <Grid item xs={6} sm={6} md={6}>
                        <Typography align='left' variant='h5' gutterBottom>
                            Pending
                        </Typography>
                        <Divider/>
                            {
                              <div>{todos.title}</div>
                            }
                    </Grid>
                    <Grid item xs={6} sm={6} md={6}>
                        <Typography align='left' variant='h5' gutterBottom>
                            Completed
                        </Typography>
                        <Divider/>
                    </Grid>
                </Grid>
            </Box>
        </>
    )
}

export default TodoContainer

我收到错误消息:

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'title')

Source
src\components\TodoContainer.tsx (25:42) @ title

  23 |     
  24 |         {
> 25 |           <div>{todos.title}</div>         |                      ^
  26 |         }
  27 |     
  28 | </Grid>

你能告诉我哪里出错了吗?

ztyzrc3y

ztyzrc3y1#

getTodoState选择器函数返回***todos状态,而不是具有todos属性的对象。

const initialState: TodoState = {
  id: 0,
  title: 'Goto Market',
  completed: false,
  important: true
} as const;

const todoSlice = createSlice({
  name: 'todos',
  initialState,
  reducers: {
    ...
  }
})

export const getTodoState = (state: { todos: TodoState }) => state.todos;

UI应仅将返回的state.todos值赋给todos,而不是使用解构赋值。
示例:

const todos = useSelector(getTodoState);

相关问题