如何在React Hook中创建新的JSON对象?

3

我有两个问题,第一个是如何在hook中添加/更新JSON项? 另一个问题是React不允许我使用从先前的JSON文件存储的名称。

我可以接受其他解决方案,因为我的输入字段是根据JSON文件动态生成的,我不确定存储或访问输入数据的最佳方法,我认为将它们作为JSON存储在React Hook中,然后将它们作为props传递到另一个组件可能是最好的。

我希望发生的事情是,在onChange事件中,我想要将数量值存储为JSON对象,并存储在Hook中,以下是我的代码:

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文件:

//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个回答

2
假设您的Quantities对象应该如下所示:
{
    <Ingredient Name>: { quantities: <value> }
}

你需要修改你的handleChange函数,让它看起来像这样。
const handleChange = (event) => {
    setQuantities({
        ...Quantities,
        [Ingredients.Name]: {
            ...(Quantities[Ingredients.Name] ?? {}),
            quantities: event.target.value
        }
    });
};

解释

在React中更新状态时,重要的是要替换对象而不是改变现有对象,因为这会告诉React重新渲染组件。通常使用扩展运算符和数组函数(如mapfilter)来完成此操作。例如:

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

请注意,展开运算符不会在第一层以下操作,也就是说,对象内部的对象将被引用复制,例如:

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

在我的答案中,我使用了空值合并运算符(??)。如果左操作数为nullundefined,它将返回右操作数。例如:

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

在我的回答中,我使用它来回退到一个空对象,如果Quantities[Ingredients.Name]未定义。

最后,当使用变量作为对象键时,我使用方括号,因为这会导致表达式在用作键之前被评估:

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

您介意给出代码的快速解释/分解,以便我完全理解吗? - lukeet
我已经加入了一些代码使用的解释,希望它能对你有所帮助。 - Matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接