How do I create a new JSON object inside a react hook?

风流意气都作罢 提交于 2020-12-12 02:05:18

问题


I have two issues first how do I add/update the JSON items within a hook? The other being that React won't let me use the name stored from a previous JSON file.

I am open to other solutions, basically, as my input field are dynamically generated from a JSON file I'm unsure of the best way to store or access the data that's input into them I think storing them in a react hook as JSON and then passing them though as props to another component is probably best.

What I want to happen is onChange I would like the quantity value to be stored as a JSON object in a Hook here's my code:

React:

import React, { useState, useEffect } from 'react';
import Data from '../shoppingData/Ingredients';
import Quantities from '../shoppingData/Quantities';

const ShoppingPageOne = (props) => {
  //element displays
  const [pageone_show, setPageone_show] = useState('pageOne');

  //where I want to store the JSON data
  const [Quantities, setQuantities] = useState({});

  useEffect(() => {
    //sets info text using Json
    if (props.showOne) {
      setPageone_show('pageOne');
    } else {
      setPageone_show('pageOne hide');
    }
  }, [props.showOne]);

  return (
    <div className={'Shopping_Content ' + pageone_show}>
      //generates input fields from JSON data
      {Data.map((Ingredients) => {
        const handleChange = (event) => {
          // this is where I'd like the Hook to be updated to contain instances of the ingredients name and quantity of each
          setQuantities(
            (Ingredients.Name: { ['quantities']: event.target.value })
          );

          console.log(Quantities);
        };

        return (
          <div className="Shopping_input" key={Ingredients.Name}>
            <p>
              {Ingredients.Name} £{Ingredients.Price}
            </p>
            <input
              onChange={handleChange.bind(this)}
              min="0"
              type="number"
            ></input>
          </div>
        );
      })}
      <div className="Shopping_Buttons">
        <p onClick={props.next_ClickHandler}>Buy Now!</p>
      </div>
    </div>
  );
};

export default ShoppingPageOne;

JSON file:

//Json data for the shopping ingredients

export default [
    {
        Name: 'Bread',
        Price: "1.10",
    },

    {
        Name: 'Milk',
        Price: "0.50",
    },

    {
        Name: 'Cheese',
        Price: "0.90",
    },

    {
        Name: 'Soup',
        Price: "0.60",
    },

    {
        Name: 'Butter',
        Price: "1.20",
    }
]

回答1:


Assuming your Quantities object is meant to look like:

{
    <Ingredient Name>: { quantities: <value> }
}

you need to change your handleChange to look like this

const handleChange = (event) => {
    setQuantities({
        ...Quantities,
        [Ingredients.Name]: {
            ...(Quantities[Ingredients.Name] ?? {}),
            quantities: event.target.value
        }
    });
};

Explanation

When updating state in React, it is important to replace objects rather than mutating existing ones, as this is what tells React to rerender components. This is commonly done using the spread operator, and with array functions such as map and filter. For example:

const myObject = { test: 1 };
myObject.test = 2; // Mutates existing object, wrong!
const myNewObject = { ...myObject, test: 2 }; // Creates new object, good!

Note the spread operator doesn't operate below the first level, what I mean by that is, objects within the object will be copied by reference, for example:

const myObject = { test : { nested: 1 } };
const myObject2 = { ...myObject };
myObject2.test.nested = 2;
console.log(myObject.test.nested); // outputs 2

Also in my answer, I have used the nullish coalescing operator (??), this will return it's right operand if the left operand is null or undefined, for example:

null ?? 'hello'; // resolves to "hello"
undefined ?? 'world'; // resolves to "world"
"foo" ?? "bar"; // resolves to "foo"

In my answer I used it to fallback to an empty object if Quantities[Ingredients.Name] is undefined.

Finally, I used square brackets when using a variable as an object key as this causes the expression to be evaluated before being used as a key:

const myKey = 'hello';
const myObject = {
    [myKey]: 'world';
};
console.log(myObject); // { hello: 'world' }


来源:https://stackoverflow.com/questions/65143385/how-do-i-create-a-new-json-object-inside-a-react-hook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!