【发布时间】:2020-08-30 15:32:43
【问题描述】:
我正在使用带有钩子的 React、Redux 和 TypeScript 构建一个待办事项应用程序。
我不知道为什么它可以成功编译但无法在浏览器中运行。
错误:
TypeError: todos.map is not a function.
我检查了todo 的类型,它是Todo[] 类型(即一个数组),相应地,它可以使用map 进行迭代。
我不知道如何解决这个问题。
此处代码:https://codesandbox.io/s/agitated-meadow-53w0u?file=/src/App.tsx
App.tsx
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { useTypedSelector } from "./index";
function AddToDo() {
const [input, setInput] = useState("");
const dispatch = useDispatch();
function handleInput(e: React.ChangeEvent<HTMLInputElement>) {
setInput(e.target.value);
}
//dispatch to store
function handleAddTodo() {
dispatch({ text: input })
setInput("");
}
return (
<div>
<input type="text" onChange={e => handleInput(e)} value={input} />
<button type="button" onClick={handleAddTodo}>
Add todo
</button>
</div>
);
}
//TodoList
export interface Todo {
text: string;
}
function TodoList() {
const todos = useTypedSelector((state) => state)
return (
<ul className="todo-list">
{todos.map((todo: Todo) => {
return <Todo todo={todo} />;
})}
</ul>
);
}
//Todo
function Todo({ todo }: { todo: Todo }) {
return <li>{todo.text}</li>;
}
function App() {
return (
<div className="App">
<AddToDo />
<TodoList />
</div>
);
}
export default App;
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider, TypedUseSelectorHook, useSelector } from 'react-redux'
import { createStore, combineReducers } from 'redux'
import App, { Todo } from './App';
//actions
const ADD_TODO = 'ADD_TODO'
type Action = AddTodo
export function addTodo(text: string) {
return {
type: ADD_TODO,
text
}
}
type AddTodo = ReturnType<typeof addTodo>
const INITIAL_STATE = [] as Todo[]
//reducer
function todoReducer(state = INITIAL_STATE, action: Action): Todo[] {
switch (action.type) {
case ADD_TODO:
const todos: Todo[] = [
...state,
{
text: action.text,
}
]
return todos
default:
return state
}
}
const todoApp = combineReducers({
todos: todoReducer
}
)
type RootState = ReturnType<typeof todoReducer>
export const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector
//store
const store = createStore(todoApp)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
【问题讨论】:
-
为什么不在这里发布您的代码?
-
我认为 todos 不是数组。
-
请给minimal reproducible example。您可能在编译时键入了 Todo[],但运行时的 值是什么?
-
您的代码框链接无效。您的 index.tsx 文件似乎不是一个好文件(它只是 app.tsx 的副本),而且,@types/redux 作为依赖项丢失了。
-
错误提示
todos不是一个数组,当你console.log(todos)..时你得到什么?
标签: reactjs typescript redux react-redux