我是React + Redux的新手,正在构建一个Todo应用程序。
类型“ {}”中缺少属性“待办事项”,但类型“ { 待办事项:Todo []; }'。 TS2741
我认为问题是我无法连接(反应-redux)状态到TodoList
。我可以确认这一点,因为我从<TodoList />
跳转到其功能组件connect(mapStateToProps)(TodoList)
,而不是connect(mapStateToProps)(TodoList)
CodeSandbox:https://codesandbox.io/s/flamboyant-dream-w7drj?file=/src/App.tsx:712-713
我已经阅读了react-redux文档,但没有找到解决方法。
代码:
import React, { useState } from 'react';
import { connect } from 'react-redux'
import { addTodo} from './index'
function AddToDo() {
const [input, setInput] = useState('')
function handleInput(e: React.ChangeEvent<HTMLInputElement>) {
setInput(e.target.value)
}
//dispatch to store
function handleAddTodo() {
addTodo(input)
setInput('')
}
return (
<div>
<input type="text" onChange={(e) => handleInput(e)}/>
<button type="button" onClick={handleAddTodo}>
Add todo
</button>
</div>
)
}
//connect
connect(null, { addTodo })(AddToDo)
//TodoList
interface Todo {
id: number
text: string
}
interface TodoState {
todos: Todo[]
}
function TodoList({ todos}:{ todos: Todo[]}) {
return (
<ul className="todo-list">
{todos.map((todo: Todo, index) => {
return <Todo todo={todo} />;
})
}
</ul>
)
}
function mapStateToProps(state:TodoState) {
return {state}
}
connect(mapStateToProps)(TodoList)
//Todo
function Todo({ todo }: { todo: Todo }) {
return (
<li>
{todo}
</li>
)
}
function App() {
return (
<div className="App">
<AddToDo />
<TodoList /> <---------------------- Error info: Property 'todos' is missing in type '{}' but required in type '{ todos: Todo[]; }'. TS2741
</div>
);
}
export default App;
答案 0 :(得分:1)
根据您的codeandbox示例,我注意到了一些问题。
TLDR-here's a working example using your code with some modifications。
让我们逐步介绍每个组件。
const todoApp = combineReducers({
todoReducer
});
应更改为:
const todoApp = combineReducers({
todos: todoReducer
});
原因:
您的整个应用是在您通过state.todos
访问待办事项的前提下进行的。如果您将代码保留为原来的样子,则必须访问state.todoReducer
。
function AddToDo() {
const [input, setInput] = useState('')
function handleInput(e: React.ChangeEvent<HTMLInputElement>) {
setInput(e.target.value)
}
//dispatch to store
function handleAddTodo() {
addTodo(input)
setInput('')
}
return (
<div>
<input type="text" onChange={(e) => handleInput(e)}/>
<button type="button" onClick={handleAddTodo}>
Add todo
</button>
</div>
)
}
应更改为:
const addToDoConnector = connect(null, { addTodo });
// store the connect function so it can be used in typings and to create component
const ConnectedTodo = addToDoConnector(AddToDo);
function AddToDo(props: ConnectedProps<typeof addToDoConnector>) {
const [input, setInput] = useState('')
function handleInput(e: React.ChangeEvent<HTMLInputElement>) {
setInput(e.target.value)
}
//dispatch to store
function handleAddTodo() {
props.addTodo(input)
setInput('')
}
return (
<div>
<input type="text" onChange={(e) => handleInput(e)}/>
<button type="button" onClick={handleAddTodo}>
Add todo
</button>
</div>
)
}
原因:
您正在文件顶部导入名为addTodo
的变量。我们需要访问AddToDo组件的addTodo
属性,以便将其调度到商店。
function TodoList({ todos}:{ todos: Todo[]}) {
return (
<ul className="todo-list">
{todos.map((todo: Todo, index) => {
return <Todo todo={todo} />;
})
}
</ul>
)
}
function mapStateToProps(state:TodoState) {
return { state }
}
connect(mapStateToProps)(TodoList)
应更改为:
// store the connect function so it can be used in typings and to create component
const todoListConnector = connect(mapStateToProps);
const ConnectedTodoList = todoListConnector(TodoList);
function TodoList({todos}: ConnectedProps<typeof todoListConnector>) {
return (
<ul className="todo-list">
{todos.map((todo: Todo, index) => {
return <Todo todo={todo} />;
})
}
</ul>
)
}
function mapStateToProps(state:TodoState) {
return state;
}
原因:
您的mapStateToProps
将状态包装在名为state
的属性中。也就是说,如果您的状态为{todos: []}
,则将其更改为{state: { todos: [] } }
。
//Todo
function Todo({ todo }: { todo: Todo }) {
return (
<li>
{todo}
</li>
)
}
应更改为:
//Todo
function Todo({ todo }: { todo: Todo }) {
return <li>{todo.text}</li>;
}
原因:
Todo是一个对象。我们想要渲染对象的文本。
function App() {
return (
<div className="App">
<AddToDo />
<TodoList />
</div>
);
}
应更改为:
function App() {
return (
<div className="App">
<ConnectedTodo />
<ConnectedTodoList />
</div>
);
}
原因:
调用connect
不会更改基础组件。您需要将该值存储在变量中或具有专用文件并export
。
让我知道您是否还有其他问题。编码愉快。
答案 1 :(得分:-1)
检查此处的工作示例,进行一些修改 CodeSandbox