Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过动态输入字段向对象数组添加值_Javascript_Reactjs - Fatal编程技术网

Javascript 通过动态输入字段向对象数组添加值

Javascript 通过动态输入字段向对象数组添加值,javascript,reactjs,Javascript,Reactjs,我一直在关注一个YouTube教程,该教程介绍如何使用React动态添加或删除输入字段 本教程的大部分内容都很容易理解,我几乎实现了我想要做的事情,但是我在添加对象时遇到了一个问题,它会复制自身,而不是添加不同的值 代码如下: import React, { useState } from "react"; import { Button, Form } from "react-bootstrap"; const countries = [

我一直在关注一个YouTube教程,该教程介绍如何使用React动态添加或删除输入字段

本教程的大部分内容都很容易理解,我几乎实现了我想要做的事情,但是我在添加对象时遇到了一个问题,它会复制自身,而不是添加不同的值

代码如下:

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

const countries = [
  {
    key: "1",
    name: "",
    value: ""
  },
  {
    key: "2",
    name: "Afghanistan",
    value: "Afghanistan"
  },
  {
    key: "3",
    name: "Albania",
    value: "Albania"
  },
  {
    key: "4",
    name: "Algeria",
    value: "Algeria"
  },
  {
    key: "5",
    name: "Angola",
    value: "Angola"
  },
  {
    key: "6",
    name: "Argentina",
    value: "Argentina"
  },
]

const listanswers = [
  {
    key: '01',
    name: '',
    value: '',
  },
  {
    key: '02',
    name: 'Yes',
    value: 'Yes',
  },
  {
    key: '03',
    name: 'No',
    value: 'No',
  },
  {
    key: '04',
    name: 'Unsure',
    value: 'Unsure',
  },
];


export default function Section1_3() {
  const [question1_7, setQuestion1_7] = useState("");
  const [instance1_7, setInstance1_7] = useState([
    {
      Country: "",
      Answer: "",
    }
  ]);

  // handle input change
  const handleInputChange = (instance, setinstance, e, index) => {
    const { name, value } = e.target;
    const list = [...instance];
    list[index][name] = value;
    setinstance(list);
  };

  // handle click event of the Remove button
  const handlRemoveInstance = (instance, setinstance, index) => {
    const list = [...instance];
    list.splice(index, 1);
    setinstance(list);
  };

  // handle click event of the Add button
  const handleAddInstance = (instance, setinstance) => {
    setinstance([...instance, instance[0]]);
  };

  return (
    <div>
      <Form>
        <Form.Group size="lg" controlId="formSection3">
          {instance1_7.map((answer, i) => {
            return (
              <div key={(i + 1) * 3}>
                <Form.Label>Instance variable 1</Form.Label>
                {console.log(answer)}
                <Form.Control
                  name="Country"
                  as="select"
                  onChange={e =>
                    handleInputChange(instance1_7, setInstance1_7, e, i)
                  }
                >
                  {countries.map(country => (
                    <option
                      key={country.key}
                      value={country.value}
                      label={country.name}
                    />
                  ))}
                </Form.Control>
                <Form.Label>Instance variable 2</Form.Label>
                <Form.Control
                  name="Answer"
                  as="select"
                  onChange={e =>
                    handleInputChange(instance1_7, setInstance1_7, e, i)
                  }
                >
                  {listanswers.map(answer => (
                    <>
                      <option
                        key={answer.key}
                        value={answer.value}
                        label={answer.name}
                      />
                    </>
                  ))}
                </Form.Control>

                {instance1_7.length !== 1 && (
                  <Button
                    variant="danger"
                    onClick={() =>
                      handlRemoveInstance(instance1_7, setInstance1_7, i)
                    }
                  >
                    Remove
                  </Button>
                )}
                {instance1_7.length - 1 === i && (
                  <Button
                    variant="success"
                    onClick={() =>
                      handleAddInstance(instance1_7, setInstance1_7, i)
                    }
                  >
                    Add
                  </Button>
                )}
              </div>
            );
          })}
        </Form.Group>
      </Form>
      <div style={{ marginTop: 20 }}>{JSON.stringify(instance1_7)}</div>
    </div>
  );
}

更新:我刚意识到您发布了解决方案:o) 下面是对问题的解释

请看一下第86行的代码好吗

// handle click event of the Add button
const handleAddInstance = (instance, setinstance) => {
   setinstance([...instance, instance[0]]);
};
您将看到在
实例[0]
上有一个复制操作。在javascript中,当您将对象作为副本传递时,该对象将作为引用传递。更改新添加对象上的值后,它也将更新其他引用上的值

如果要复制,则需要创建克隆

有多种方法可以做到这一点。例如,您可以使用JSON API删除引用:

JSON.parse(JSON.stringify(instance[0]))
这比:

Object.assign({}, instance[0])
基准

仔细查看
对象.assign()


或者,您可能需要由
lodash
提供的名为
cloneDeep
的函数,并按以下方式导入:

import cloneDeep from 'lodash/cloneDeep';
然后:

setinstance([...instance, cloneDeep(instance[0]]));
最后,;我建议使用本机赋值方法
Object.assign({},实例[0])


祝你好运:o)

请编辑问题并添加答案?非现场代码的链接必须附有问题代码。谢谢你提供的链接,我确实没有把整个帖子做得像它应该做的那样。不管怎样,我还是能成功的…我真蠢!感谢您花时间提供这么好的解释,您使用Object.assign提供的解决方案正是我目前需要的,以便使我的代码更干净:)不客气,很高兴它能帮助我:o)
setinstance([...instance, cloneDeep(instance[0]]));
// handle click event of the Add button
const handleAddInstance = (instance, setinstance) => {
   setinstance([...instance, Object.assign({}, instance[0])]);
};