javascript 在React JS中创建待办事项列表时,我得到了-(无法在渲染不同组件(`DisplayTasks`)时更新组件(`App`))

xdyibdwo  于 11个月前  发布在  Java
关注(0)|答案(1)|浏览(122)

这是我的Textinserter.js

  • 在这个JS文件中,我有一个输入任务的文本字段和一个将该任务添加到任务数组的按钮 *
// 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>
    </>
  );
}

字符串

这里是Displaytasks.js

  • 这段代码显示任务数组中的任务,也有一个删除按钮,应该删除特定的任务。但我得到一个警告-*
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警告:无法在呈现不同组件(DisplayTasks)时更新组件(App)。若要在DisplayTasks中找到错误的setState()调用,请按照DisplayTasks(http://localhost:3000/static/js/slogle. js:122:3)中https://reactjs.org/link/setstate-in-render在App(http://localhost:3000/static/js/slogle. js:33:76)的div中所述的堆栈跟踪

这是我的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>
  );
}

dfty9e19

dfty9e191#

我没有试过自己运行代码,但似乎问题出在你的DisplayTasks组件上。
下面是你的原始代码。

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>
    // ...
  );
}

字符串
您的deleteTask函数更新App组件的状态,并且在渲染期间调用它,因为您已经将deleteTask(task.id)放入button的onClick prop中。
onClick应该是一个当它被点击时应该运行的函数。相反,你调用的是一个deleteTask函数,它的返回值(是void)是作为一个prop给出的。
你只需要把它改成一个匿名函数,就像下面这样。

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>
    // ...
  );
}


或者,也许你可以改变你的deleteTask函数来返回一个函数并使用它。

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>
    // ...
  );
}

相关问题