I am learning react with typescript and i have the following problem:
App.tsx
import { useState } from 'react';
import Header from './components/Header';
import Tasks from './components/Tasks';
import { TaskType } from './components/Task'
function App() {
const [tasks, setTasks] = useState<TaskType[]>([
{
id: 0,
text: 'Doctors Appointment',
day: 'Feb 4th at 2:30 pm',
reminder: true
},
{
id: 1,
text: 'Meeting at school',
day: 'Feb 5th at 3:50 pm',
reminder: true
},
{
id: 2,
text: 'food shopping',
day: 'Feb 4th at 2:30 pm',
reminder: false
}
]);
const deleteTask = (id: number) => {
console.log('Delete', id);
}
// Delete task function
const someTitle = 'Title';
return (
<div className='container'>
<Header title={someTitle}></Header>
<Tasks tasks={tasks} onDelete={() => deleteTask}></Tasks>
</div>
);
}
export default App;
The method deleteTask() is not getting called from the inner components below: (Tasks are a list of Task)
Tasks.tsx
import Task from './Task'
import { TaskType } from './Task'
export interface ITasksListProps {
tasks: TaskType[]
onDelete: React.MouseEventHandler
}
const Tasks: React.FC<ITasksListProps> = ({tasks, onDelete}) => {
return (
<>
{tasks.map ((task) => (
<Task key={task.id} task={task} onDelete={() => onDelete}/>
))}
</>
)
}
export default Tasks
Task.tsx
import { FaTimes } from 'react-icons/fa'
export type TaskType = {
id: number,
text: string,
day: string,
reminder: boolean
}
export interface ITaskProps {
task: TaskType
onDelete: React.MouseEventHandler
}
const Task = ({task, onDelete}: ITaskProps) => {
return (
<div className='task'>
<h3>{task.text} <FaTimes style={{ color: 'red', cursor: 'pointer' }} onClick={onDelete} /></h3>
<p>{task.day}</p>
</div>
)
}
export default Task
Where is the error here? I can't figure out how to retain those states and simultaneously get the method to be called properly
CodePudding user response:
Follow the updated files, even "onDelete" removes your tasks. Let me know if it worked or not. Codesandbox here
// App.tsx
import { useState } from "react";
import Header from "./components/Header";
import Tasks from "./components/Tasks";
import { TaskType } from "./components/Task";
function App() {
const defaultState = [
{
id: 0,
text: "Doctors Appointment",
day: "Feb 4th at 2:30 pm",
reminder: true
},
{
id: 1,
text: "Meeting at school",
day: "Feb 5th at 3:50 pm",
reminder: true
},
{
id: 2,
text: "food shopping",
day: "Feb 4th at 2:30 pm",
reminder: false
}
];
const [tasks, setTasks] = useState<TaskType[]>(defaultState);
const deleteTask = (id: number) => {
console.log("id is", id);
const filteredTasks = tasks.filter((each) => each.id !== id);
setTasks(filteredTasks);
};
// Delete task function
const someTitle = "Title";
return (
<div className="container">
<Header title={someTitle}></Header>
<Tasks {...{ tasks, onDelete: deleteTask }}></Tasks>
</div>
);
}
export default App;
// Header.tsx
export default function Header(props: { title: string }) {
const { title } = props;
return <div>Header {title}</div>;
}
// Task.tsx
import { FaTimes } from "react-icons/fa";
export type TaskType = {
id: number;
text: string;
day: string;
reminder: boolean;
};
export interface ITaskProps {
task: TaskType;
onDelete: Function;
}
const Task = ({ task, onDelete }: ITaskProps) => {
return (
<div className="task">
<h3>
{task.text}{" "}
<FaTimes
style={{ color: "red", cursor: "pointer" }}
onClick={() => onDelete(task.id)}
/>
</h3>
<p>{task.day}</p>
</div>
);
};
export default Task;
// Tasks.tsx
import React from "react";
import Task from "./Task";
import { TaskType } from "./Task";
export interface ITasksListProps {
tasks: TaskType[];
onDelete: Function;
}
const Tasks: React.FC<ITasksListProps> = ({ tasks, onDelete }) => {
return (
<>
{tasks.map((task) => (
<Task key={task.id} {...{ task, onDelete }} />
))}
</>
);
};
export default Tasks;
CodePudding user response:
Because you are using it wrong
<Tasks tasks={tasks} onDelete={() => deleteTask}></Tasks>
Here you should do for example
<Tasks tasks={tasks} onDelete={() => deleteTask(5)}></Tasks>
So what is happening is that
onClick={onDelete}
basically means that onClick = onDelete
but
onDelete={() => deleteTask}
means onDelete = () => { deleteTask }
you are just referencing the method but not invoking it.