0

I'm making a form that has text areas and a multiple checkboxes to define the categories. I can correctly update the categories if they are in a state apart, but I can't then integrate them in the main object.

import React, { useState } from "react";
import { Button, ToggleButton, ToggleButtonGroup, Form } from "react-bootstrap";

import checkboxes from "./components/checkboxes";
import Checkbox from "./components/Checkbox";

const StandAdd = () => {
  const [checkedItems, setCheckedItems] = useState([]);

  const [item, setItem] = useState({
    title: "",
    kindof: "",
    website: "",
    image01: "",
    image02: "",
    image03: "",
    categories: []
  });

  const {
    title,
    kindof,
    website,
    image01,
    image02,
    image03,
    categories
  } = item;

  const handleInputChange = event => {
    event.preventDefault();
    setItem(
      {
        ...item,
        [event.target.name]: event.target.value
      },
      {
        ...categories,
        [event.target.name]: event.target.checked
      }
    );
  };

  const handleSubmit = event => {
    event.preventDefault();
    console.log("item", { item });
    // console.log(title, kindof, website, image01, image02, image03, categories)
    console.log("checkedItems: ", checkedItems);
  };

  const handleCheckChange = event => {
    setCheckedItems({
      ...checkedItems,
      [event.target.name]: event.target.checked
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <Form.Group controlId="title">
        <Form.Control
          name="title"
          type="text"
          placeholder="Enter Stand's Name"
          onChange={handleInputChange}
        />
      </Form.Group>

      {checkboxes.map(item => (
        <label key={item.key}>
          {item.label}{" "}
          <Checkbox
            name={item.name}
            checked={checkedItems[item.name]}
            onChange={handleCheckChange}
          />{" "}
        </label>
      ))}

      <ToggleButtonGroup type="radio" name="kindof" value={kindof}>
        <ToggleButton
          onChange={handleInputChange}
          checked={kindof === "design"}
          value={"design"}
        >
          Design
        </ToggleButton>
        <ToggleButton
          onChange={handleInputChange}
          checked={kindof === "food"}
          value={"food"}
        >
          Food
        </ToggleButton>
      </ToggleButtonGroup>
      <Form.Group controlId="website">
        <Form.Control
          name="website"
          type="text"
          placeholder="Enter Stand's Website"
          onChange={handleInputChange}
        />
      </Form.Group>
      <Form.Group controlId="image01">
        <Form.Control
          name="image01"
          type="text"
          placeholder="Enter Image 1"
          onChange={handleInputChange}
        />
      </Form.Group>
      <Form.Group controlId="image02">
        <Form.Control
          name="image02"
          type="text"
          placeholder="Enter Image 2"
          onChange={handleInputChange}
        />
      </Form.Group>
      <Form.Group controlId="image03">
        <Form.Control
          name="image03"
          type="text"
          placeholder="Enter Image 3"
          onChange={handleInputChange}
        />
      </Form.Group>
      <Button variant="primary" type="submit">
        Submit
      </Button>
    </form>
  );
};

export default StandAdd;

When I console.log the item I get an object:

title: "title"
kindof: ""
website: ""
image01: ""
image02: ""
image03: ""
categories: Array[0]

I would like to get something like

title: "title"
kindof: ""
website: ""
image01: ""
image02: ""
image03: ""
categories: [jewerly, clothing]

working example : https://codesandbox.io/s/react-array-into-object-dmyrz?file=/src/App.js

is there any way to do that? thanks!

3
  • What do you want populated into categories and where would you try to update it? I don't see any inputs for it nor any handler that updates it. Commented Jun 26, 2020 at 8:15
  • ok. I want to create the object to pass to a REST API + MYSQL that I prepared Commented Jun 26, 2020 at 8:29
  • working example : codesandbox.io/s/react-array-into-object-dmyrz?file=/src/App.js Commented Jun 26, 2020 at 8:30

1 Answer 1

1

You can update your handleCheckChange handler to update the item.categories state.

  1. Destructure checked and name from the event since react events are nullified and dumped back in the event pool. This is done so the event values are usable in other asynchronous code like state update callbacks.
  2. Use a functional state update to update the item.categories property. If the current checkbox value it truthy, i.e. checked, then simply append the name to the array (spreading in the existing state OFC), otherwise, filter it out of the categories array.

handleCheckChange

const handleCheckChange = event => {
  const { checked, name } = event.target; // 1.
  setCheckedItems({
    ...checkedItems,
    [name]: checked
  });

  setItem(prevItems => ({ // 2.
    ...prevItems,
    categories: checked
      ? [...prevItems.categories, name]
      : prevItems.categories.filter(category => category !== name)
  }));
};

Edit React Array into object

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.