属性 'toDos' 在 TS2339 类型上不存在
Property 'toDos' does not exist on type TS2339
我是初学者,第一次学习ts。预先感谢您分享您的知识。
我正在制作一个待办事项列表。我用反应来完成它。但是现在我是用react和typescript一起来完成代码的。
在我看来 'reducer' 工作不正常。我该如何操作?如果你让我知道,我将不胜感激。这是 '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;
这里发生的事情是由于混淆的命名。您创建了一个自定义挂钩 useState
,它与内置的 React 挂钩同名,但您用错了。
这里出现错误:
const { toDos, completed } = useState<ITodo>(); Error part
因为这个:
import React, { useState } from "react";
您想使用您的自定义 useState
挂钩,它 returns 一个具有属性 toDos
和 completed
的对象。但是您没有导入那个钩子,而是导入了内置的 React 钩子 useState
,其中 returns 一个包含两个条目(state
和 setState
)的数组。
进入 context.tsx
并将您的自定义挂钩重命名为更明确的名称,例如 useTodosState
和 useTodosDispatch
。这不是严格要求,但它会让生活变得更轻松!
然后进入 App.tsx
并将 useState
替换为 useTodosState
,确保从 context.tsx
导入它。既然您已经确定要使用哪个钩子,您就不必担心 IDE 从 React 自动导入 useState
。
我是初学者,第一次学习ts。预先感谢您分享您的知识。 我正在制作一个待办事项列表。我用反应来完成它。但是现在我是用react和typescript一起来完成代码的。
在我看来 'reducer' 工作不正常。我该如何操作?如果你让我知道,我将不胜感激。这是 '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;
这里发生的事情是由于混淆的命名。您创建了一个自定义挂钩 useState
,它与内置的 React 挂钩同名,但您用错了。
这里出现错误:
const { toDos, completed } = useState<ITodo>(); Error part
因为这个:
import React, { useState } from "react";
您想使用您的自定义 useState
挂钩,它 returns 一个具有属性 toDos
和 completed
的对象。但是您没有导入那个钩子,而是导入了内置的 React 钩子 useState
,其中 returns 一个包含两个条目(state
和 setState
)的数组。
进入 context.tsx
并将您的自定义挂钩重命名为更明确的名称,例如 useTodosState
和 useTodosDispatch
。这不是严格要求,但它会让生活变得更轻松!
然后进入 App.tsx
并将 useState
替换为 useTodosState
,确保从 context.tsx
导入它。既然您已经确定要使用哪个钩子,您就不必担心 IDE 从 React 自动导入 useState
。