简体   繁体   中英

How to add an object inside an array inside an object in React?

I'm trying to insert a task with multiple fields like title, text, and tag only in the 'To Do' category. It would be an object inside an array, inside an object. The way I'm implementing it is totally wrong, and it's generating a chain of objects inside another object. How could I be performing so that the data looks the same as in the Table?

This is the way I need the data to be saved:

const Table = [
  {
    id: uuidv4(),
    title: "To do",
    tasks: [
      {
        id: uuidv4(),
        title: "Learn JavaScript",
        text: "lorem ipsum",
        tag: "tag1",
      },
      {
        id: uuidv4(),
        title: "Learn Git",
        text: "lorem ipsum",
        tag: "tag2",
      },
    ],
  },
  {
    id: uuidv4(),
    title: "Doing",
    tasks: [
      {
        id: uuidv4(),
        title: "Learn CSS",
        text: "lorem ipsum",
        tag: "tag1",
      },
    ],
  },
  {
    id: uuidv4(),
    title: "Done",
    tasks: [
      {
        id: uuidv4(),
        title: "Learn HTML",
        text: "lorem ipsum",
        tag: "tag1",
      },
    ],
  },
];

This is the code I made

  import React, { useState } from "react";
import Input from "./Input";
import "./App.css";

const App = () => {
  const [tasks, setTasks] = useState([]);
  function addTask(task) {
    const newTask = { ...task };
    newTask[0] = {
      ...tasks[0],
      arrayTasks: task,
    };
    setTasks([...tasks, newTask]);
  }
  return (
    <div>
      <Input onAdd={addTask} />
    </div>
  );
};

export default App;

and this one:

import { useState } from "react";

const Input = ({ onAdd }) => {
  const [title, setTitle] = useState("");
  const [text, setText] = useState("");
  const [tag, setTag] = useState("");
  const [status, setStatus] = useState("ToDo");

  const onSubmit = (e) => {
    e.preventDefault();

    if (!text || !title) {
      alert("Please enter a task with a title");
      return;
    }
    const number = Math.floor(Math.random() * 10000) + 1;
    const id = "" + number;
    onAdd({ title, text, tag, status, id });
    setTitle("");
    setText("");
    setTag("");
    setStatus("ToDo");
  };

  return (
    <div>
      <input
        type="text"
        placeholder="Add Title"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
      />
      <input
        type="text"
        placeholder="Add Task"
        value={text}
        onChange={(e) => setText(e.target.value)}
      />
      <input
        type="text"
        placeholder="Insert you tag"
        value={tag}
        onChange={(e) => setTag(e.target.value)}
      />
      <button type="submit" onClick={onSubmit}>
        Save Task
      </button>
    </div>
  );
};

export default Input;

This is the output

if you expect your task state to be like the table array. so i think you need first to refer to which item in the array to update. so i suggest you need to pass an extra param to the function 'id of the target item or row' .

and so, you can try something like this.

// the second param is the id of target row or item which contain the tasks obj.

function addTask(task, id) {
    const tasksCopy = [...tasks]; // should be a copy of table variable

    const targetObjIndex = tasksCopy.findIndex((tbl) => tbl.id === id);
    const resetOfTheArray = tasksCopy.filter((tbl) => tbl.id !== id);

    let targetItem = tasksCopy[targetObjIndex];

    targetItem = { ...targetItem, tasks: [...targetItem.tasks, task] };

  return [...resetOfTheArray, targetItem];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM