【问题标题】:Property 'toDos' does not exist on type TS2339TS2339 类型上不存在属性“toDos”
【发布时间】:2021-05-08 11:57:23
【问题描述】:

我是第一次学习 ts 的初学者。提前感谢您分享您的知识。 我正在制作一个 todolist。我用反应来完成它。但是现在我是用 react 和 typescript 一起来完成代码的。

在我看来,“减速器”工作不正常。我该如何操作?如果你让我知道,我将不胜感激。这是带有表面错误的“App.tsx”代码。

import React, { useState } from "react";
import Add from "./Add";
import List from "./List";
import ToDo from "./ToDo";
import Title from "./Title";
import Progress from "./Progress";
import styled from "styled-components";

interface ITodo {
  toDos: string;
  completed: boolean;
}

function App() {
  const { toDos, completed } = useState<ITodo>(); ???? Error part
  return (
    <Title>
      <Add />
      <Progress />
      <Lists>
        <List title={toDos.length !== 0 ? "To Dos" : ""}>
          {toDos.map((toDo: any) => (
            <ToDo key={toDo.id} id={toDo.id} text={toDo.text} isCompleted={false} />
          ))}
        </List>
        <List title={completed.length !== 0 ? "Completed" : ""}>
          {completed.map((toDo: any) => (
            <ToDo key={toDo.id} id={toDo.id} text
              {...toDo.text} isCompleted />
          ))}
        </List>
      </Lists>
    </Title>
  );
}

export default App;

这段代码是我认为有问题的“reducer.tsx”代码。

import { v4 as uuidv4 } from "uuid";
import { ADD, DEL, COMPLETE, UNCOMPLETE, EDIT } from "./actions";

export const initialState = {
  toDos: [],
  completed: [],
};

const reducer = ({ state, action }: any) => {
  switch (action) {
    case ADD:
      return {
        ...state,
        toDos: [...state.toDos, { text: action.payload, id: uuidv4() }],
      };
    case DEL:
      return {
        ...state,
        toDos: state.toDos.filter((toDo: { id: number; }) => toDo.id !== action.payload),
      };
    case COMPLETE:
      const target = state.toDos.find((toDo: { id: number; }) => toDo.id === action.payload);
      return {
        ...state,
        toDos: state.toDos.filter((toDo: { id: number; }) => toDo.id !== action.payload),
        completed: [...state.completed, { ...target }],
      };
    case UNCOMPLETE:
      const aTarget = state.completed.find(
        (toDo: { id: any; }) => toDo.id === action.payload
      );
      return {
        ...state,
        toDos: [...state.toDos, { ...aTarget }],
        completed: state.completed.filter(
          (complete: { id: number; }) => complete.id !== action.payload
        ),
      };
    case EDIT:
      const bTarget = state.toDos.find((toDo: { id: number; }) => toDo.id === action.id);
      const rest = state.toDos.filter((toDo: { id: number; }) => toDo.id !== action.id);
      return {
        ...state,
        toDos: rest.concat({ ...bTarget, text: action.payload }),
      };
    default:
      return;
  }
};

export default reducer;

此代码是“context.tsx”代码。

import React, { createContext, useReducer, useContext } from 'react';
import reducer, { initialState } from "./reducer";

export type Todo = {
  id: number;
  text: string;
  done: boolean;
};

export type TodosState = Todo[];

const ToDosContext = createContext<TodosState | any>(undefined);

const ToDosProvider = ({ children }: { children: React.ReactNode }) => {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <ToDosContext.Provider value={{ state, dispatch }}>
      {children}
    </ToDosContext.Provider>
  );
};

export const useDispatch = () => {
  const { dispatch } = useContext(ToDosContext);
  return dispatch;
};

export const useState = () => {
  const { state } = useContext(ToDosContext);
  return state;
};

export default ToDosProvider;

【问题讨论】:

    标签: typescript react-hooks reducers react-tsx


    【解决方案1】:

    这里发生的事情是由于命名混乱。你创建了一个自定义钩子useState,它与一个内置的 React 钩子同名,但你使用了错误的钩子。

    你在这里得到一个错误:

    const { toDos, completed } = useState<ITodo>(); ? Error part
    

    因为这个:

    import React, { useState } from "react";
    

    您想使用自定义的useState 钩子,它返回一个具有toDoscompleted 属性的对象。但是您没有导入那个钩子,而是导入了内置的 React 钩子 useState,它返回一个包含两个条目(statesetState)的数组。

    进入context.tsx 并将您的自定义挂钩重命名为不那么含糊的名称,例如useTodosStateuseTodosDispatch。这不是严格要求,但它会让生活变得更轻松!

    然后进入App.tsx并将useState替换为useTodosState,确保从context.tsx导入。既然你想使用哪个钩子已经毫无疑问了,你就不用担心你的 IDE 会从 React 自动导入 useState

    【讨论】:

    • 感谢您,我解决了这个问题。但是又出现了一个问题。你能告诉我这个吗?谢谢你的辛劳工作。 TypeError:无法解构“对象(...)(...)”的属性“toDos”,因为它未定义。 const { toDos, completed } = useTodosState();这仍然是问题。
    • 听起来您可能不在 ToDosProvider 中。确保将整个 App 组件包装在 ToDosProvider 中。
    猜你喜欢
    • 2016-03-14
    • 2017-02-25
    • 2021-11-24
    • 2019-01-11
    • 2021-10-15
    • 2020-12-13
    • 2021-08-04
    • 2020-07-01
    • 2021-06-03
    相关资源
    最近更新 更多