This is my Textinserter.js
In this JS file I have a text field to enter the task and a button to add that task to a tasks array
// Import React and useState from the 'react' library
import React, { useState } from "react";
// Create a functional component named Textinserter
export default function Textinserter({ tasks, setTasks }) {
// Initialize state variables using useState hook: tasks and tasksInput
const [tasksInput, setTasksInput] = useState("");
// Function to handle changes in the input field
const handleOnChange = (e) => {
// Update tasksInput state with the value entered in the input field
setTasksInput(e.target.value);
};
// Function to add a task to the tasks list
const addTask = () => {
// Check if the trimmed input is not an empty string
if (tasksInput.trim() !== "") {
// Create a new task object with an ID and name
const newTask = { id: tasks.length + 1, name: tasksInput };
// Update tasks state using the functional form of setTasks
setTasks((prevTasks) => [...prevTasks, newTask]);
// Clear the tasksInput state after adding the task
setTasksInput("");
}
};
// Return JSX for the component
return (
<>
<div className="mb-3">
{/* Input field and label */}
<label htmlFor="exampleInputEmail1" className="form-label">
Enter The Task
</label>
<input
type="text"
className="form-control"
id="exampleInputEmail1"
aria-describedby="emailHelp"
onChange={handleOnChange} // Handle input changes with handleOnChange function
value={tasksInput}
/>
{/* Button to add a task */}
<div className="conatiner text-center">
<button className="btn btn-danger my-3" onClick={addTask}>
Add Task
</button>
</div>
</div>
</>
);
}
This is the Displaytasks.js
This code displays the tasks inside the Tasks array and also has a delete Button which should delete a particular task. But I am getting a warning –
import React from "react";
// Component to display tasks
export default function DisplayTasks({ tasks, onDelete }) {
const deleteTask = (taskId) => {
// Filter out the task with the matching ID and update tasks array
const updatedTasks = tasks.filter((task) => task.id !== taskId);
onDelete(updatedTasks);
};
// Styling for the main container
const myStyle = {
backgroundColor: "#0D6EFD",
padding: "15px",
borderRadius: "10px",
};
return (
<div
// Conditional styling based on the tasks length
style={
tasks.length === 0 ? { ...myStyle, visibility: "hidden" } : myStyle
}
>
{/* Heading for the tasks */}
<h1 className="text-center text-light mb-4">Today's Tasks</h1>
{tasks && tasks.length > 0 ? ( // Check if tasks exist and not empty
<ul className="list-group" style={{ width: "100%" }}>
{tasks.map((task) => (
<div
key={task.id}
className="d-flex justify-content-between align-items-center"
>
{/* Container for each task */}
<span
className="d-inline-block w-100 overflow-hidden m-2"
style={{ borderRadius: "10px" }} // Styling for each task container
>
{/* List item for the task */}
<li className="list-group-item" aria-current="true">
{task.name}
</li>
</span>
{/* Button to delete the task */}
<button className="btn btn-danger" onClick={deleteTask(task.id)}>
Delete
</button>
</div>
))}
</ul>
) : (
// Display if tasks array is empty or undefined
<p>No tasks available</p>
)}
</div>
);
}
App.js:10 Warning: Cannot update a component (
App) while rendering a different component (DisplayTasks). To locate the bad setState() call insideDisplayTasks, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
at DisplayTasks (http://localhost:3000/static/js/bundle.js:122:3)
at div
at App (http://localhost:3000/static/js/bundle.js:33:76)
This is my App.js
import "./App.css";
import Textinserter from "./Components/Textinserter";
import DisplayTasks from "./Components/DisplayTasks";
import { useState } from "react";
export default function App() {
const [tasks, setTasks] = useState([]); // Define tasks and setTasks in App component
const handleTaskDeletion = (updatedTasks) => {
setTasks(updatedTasks);
};
return (
<div className="container mt-5">
<Textinserter tasks={tasks} setTasks={setTasks} />
<DisplayTasks tasks={tasks} onDelete={handleTaskDeletion} />
</div>
);
}
>Solution :
I haven’t tried to run the code myself, but it seems like the problem is in your DisplayTasks component.
below is your original code..
import React from "react";
// Component to display tasks
export default function DisplayTasks({ tasks, onDelete }) {
const deleteTask = (taskId) => {
// Filter out the task with the matching ID and update tasks array
const updatedTasks = tasks.filter((task) => task.id !== taskId);
onDelete(updatedTasks);
};
return (
// ...
<button className="btn btn-danger" onClick={deleteTask(task.id)}>
Delete
</button>
// ...
);
}
your deleteTask function updates the state of App component, and it is called during render, since you have put deleteTask(task.id) into button’s onClick prop.
onClick should be a function that should be ran when it is clicked. instead, you are calling a deleteTask function and it’s return (which is void) is given as a prop.
you just have to change it to a anonymous function, like below
import React from "react";
// Component to display tasks
export default function DisplayTasks({ tasks, onDelete }) {
const deleteTask = (taskId) => {
// Filter out the task with the matching ID and update tasks array
const updatedTasks = tasks.filter((task) => task.id !== taskId);
onDelete(updatedTasks);
};
return (
// ...
<button className="btn btn-danger" onClick={() => deleteTask(task.id)}>
Delete
</button>
// ...
);
}
or, maybe you could change your deleteTask function to return a function and use it.
import React from "react";
// Component to display tasks
export default function DisplayTasks({ tasks, onDelete }) {
const deleteTask = (taskId) => () => {
// Filter out the task with the matching ID and update tasks array
const updatedTasks = tasks.filter((task) => task.id !== taskId);
onDelete(updatedTasks);
};
return (
// ...
<button className="btn btn-danger" onClick={deleteTask(task.id)}>
Delete
</button>
// ...
);
}