在待办事项应用中不断出现类型错误。我正在尝试将isComplete属性设置为true。
错误:
TypeError: Cannot set property 'isCompleted' of undefined
我的complete_todo.js文件:
import { TodoContext } from './todo_ctx';
const MarkComplete = (index) => {
const [tasks, setTodos] = useContext(TodoContext);
const newTask = [...tasks];
newTask[index].isCompleted = true;
setTodos(newTask);
return (
<button onClick={MarkComplete}>Mark Complete</button>
);
}
export default MarkComplete;
我的todo_ctx.js文件:
import React, { useState, createContext} from 'react';
export const TodoContext = createContext();
export const TodoProvider = (props) => {
const [tasks, setTodos] = useState([
{
id: 1,
task: 'Learn React',
description: 'Build a todo app in React',
isCompleted: false
},
{
id: 2,
task: 'Learn Node',
description: 'Build a Node API',
isCompleted: false
},
{
id: 3,
task: 'Learn Flutter',
description: 'Complete Flutter Course',
isCompleted: false
}
]);
return (
<TodoContext.Provider value={[tasks, setTodos]}>
{props.children}
</TodoContext.Provider>
)
}
我是React的新手,在这里我缺少什么吗?
答案 0 :(得分:0)
您的代码中几乎没有错误。
hook
或function
内部更新状态。index
,则可以传递任务。我对您的代码进行了一些更改,请尝试。
import React, { useState, createContext, useContext, Component } from 'react';
import './App.css';
export const TodoContext = createContext();
export const TodoProvider = (props) => {
const [tasks, setTodos] = useState([
{
id: 1,
task: 'Learn React',
description: 'Build a todo app in React',
isCompleted: false
},
{
id: 2,
task: 'Learn Node',
description: 'Build a Node API',
isCompleted: false
},
{
id: 3,
task: 'Learn Flutter',
description: 'Complete Flutter Course',
isCompleted: false
}
]);
return (
<TodoContext.Provider value={[tasks, setTodos]}>
<MarkComplete />
</TodoContext.Provider>
)
}
const MarkComplete = (props) => {
const [tasks, setTodos] = useContext(TodoContext);
function todoHandler(taskId) {
const newTask = tasks.map(task => {
if (task.id === taskId) {
task.isCompleted = !task.isCompleted;
}
return task;
});
setTodos(newTask);
}
return (
<div >
<table>
<thead>
<tr>
<th>Task Id</th>
<th>Task</th>
<th>isCompleted</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{tasks.map(task => (
<tr key={task.id}>
<td>{task.id}</td>
<td>{task.task}</td>
<td>{String(task.isCompleted)}</td>
<td><button onClick={() => todoHandler(task.id)}>Mark Complete ({task.id})</button></td>
</tr>
))}
</tbody>
</table>
</div>
);
}
function App() {
return <TodoProvider />
}
export default App;
代码和框链接:
答案 1 :(得分:0)
您是否已使用提供程序包装了应用程序?
示例:
import { TodoProvider } from "./src/context/todo_ctx.js";
const App = createAppContainer(navigator);
export default () => {
return (
<TodoProvider>
<App />
</TodoProvider>
);
};
答案 2 :(得分:0)
因此,我认为您不需要那里的上下文,尤其是您使用它的方式。我为您尝试过,我知道这是否有帮助:
import React, { useState } from "react";
const Todos = () => {
const [tasks, setTodos] = useState([
{
id: 1,
task: "Learn React",
description: "Build a todo app in React",
isCompleted: false
},
{
id: 2,
task: "Learn Node",
description: "Build a Node API",
isCompleted: false
},
{
id: 3,
task: "Learn Flutter",
description: "Complete Flutter Course",
isCompleted: false
}
]);
const setTodoHelper = taskId => {
setTodos(
tasks.map(x =>
x.id === taskId ? { ...x, isCompleted: !x.isCompleted } : x
)
);
};
return (
<>
{tasks.map(task => (
<Todo key={task.id} {...task} setTodoHelper={setTodoHelper} />
))}
</>
);
};
const Todo = ({ id, setTodoHelper, isCompleted }) => {
return (
<>
<div>{id}</div>
<div>completed: {String(isCompleted)} </div>
<button onClick={() => setTodoHelper(id)}>Mark Complete</button>
</>
);
};
export default Todos;