如何将用户输入的输入保存为 React 中的数组状态

Posted

技术标签:

【中文标题】如何将用户输入的输入保存为 React 中的数组状态【英文标题】:How to save input entered by the user in a state which is an array in React 【发布时间】:2019-09-26 20:47:32 【问题描述】:

整个想法是让用户在表单中输入并在 JSON 对象中显示他们的输入。在状态下,我有一个数组,里面还有另一个数组。

我的 Form.js 是这样的,

state= 
    groups:[
      typeA:[],
      typeB:[]
    ],
    credentials: false
    ;

    change = e =>
        this.setState([e.target.name]: e.target.value)
    ;

    handleSubmit(event) 
        event.preventDefault();
        this.setState(
          credentials: true 
        );
      
render()
        return(
            <div class="classform">
            <form >
                <label>
                    Field1:
                    <br/>
                    <input type="text"
                    name="typeA"
                    placeholder="Type A"
   //store it as the first element of the type A
                    value=this.state.groups.typeA[0] 
                    onChange=this.change.bind(this)
                 />
  //other fields with the same code

随后,Field2 将被存储为类型 A 的第二个元素 然后,Field3 和 Field4 将被存储为 B 类型数组的 2

我希望代码能给我这样的输出:

"typeA": ["field1 value", "field2 value"],
"typeB": ["field3 value", "field4 value"]

我是 React 的初学者,我无法将字段值存储为数组状态。

【问题讨论】:

【参考方案1】:

为了简单起见,我将推荐以下解决方案, 您可以管理不同状态变量中的输入值,并在提交时将它们更改为您想要的输出,而不是在状态中使用嵌套数组。

state = 
  field1: '',
  field2: '',
  field3: '',
  field4: '',

change = e => 
  this.setState([e.target.name]: e.target.value)
;

handleSubmit(event) 
  event.preventDefault();
  const  field1, field2, field3, field4  = this.state;
  // This is your output
  const output = [typeA: [field1, field2], typeB: [field2, field3]];
  this.setState(
    credentials: true 
  );

render()
  return(
    <div class="classform">
      <form >
        <label>
          Field1:
          <br/>
          <input type="text"
            name="field1"
            placeholder="Type A"
            value=this.state.field1
            onChange=this.change
          />
        </label>
        <label>
          Field2:
          <br/>
          <input type="text"
            name="field2"
            placeholder="Type A"
            value=this.state.field2
            onChange=this.change
          />
        </label>

【讨论】:

【参考方案2】:

试试这个:

import React,  Component  from "react";

export default class App extends Component 
  constructor(props) 
    super(props);

    this.state = 
      groups: [
        
          typeA: [],
          typeB: []
        
      ],
      credentials: false
    ;
  

  change = (e, key) => 
    let  groups  = this.state;

    let myVal = groups[0][e.target.name];
    // or if you want to add value in an object likr [value: 'abcd']
    myVal[0][key] = e.target.value;
    groups[0][e.target.name] = myVal;
    console.log("TCL: App -> groups", groups);
    this.setState( groups );
  ;

  render() 
    return (
      <div>
        <input
          type="text"
          name="typeA"
          placeholder="Type A"
          value=this.state.groups[0].typeA[0].value2
          onChange=e => this.change(e, "value2")
        />
        <input
          type="text"
          name="typeA"
          placeholder="Type A2"
          value=this.state.groups[0].typeA[0].value
          onChange=e => this.change(e, "value")
        />
        <br />
        <input
          type="text"
          name="typeB"
          placeholder="Type b"
          value=this.state.groups[0].typeB[0].value
          onChange=e => this.change(e, "value")
        />
      </div>
    );
  



【讨论】:

这给了我一个错误 TypeError: Unable to get property '0' of undefined or null reference。我是否也需要更改输入标签内的“名称” 仍然报同样的错误。我还尝试了 myVal = groups[e.target.name][0] (这样它就需要 name="typeA" 然后插入 [0] index )。你认为我应该使用地图来分配数组值吗? 你能再试一次吗! 不!仍然无法正常工作:(它甚至没有进入 return 。给出相同的错误“TypeError: Unable to get property '0' of undefined or null reference” 哇!有效!对于后续列,只有一件事,例如 col2(typeA 数组的第二个元素)和 col 3 和 col 4(typeB 数组中的两个元素)。应该如何改变价值观?假设我将 包装在 map 函数中,但是我应该如何更改 chnage 函数中的值索引 【参考方案3】:

给每个输入一个自定义属性,例如data-group="typeA"。在您的 on change 函数中获取该值并将这些值添加到正确的数组中。

<input
  type="text"
  name="col2"
  placeholder="Type A"
  data-group="typeA" // add custom attribute typeA | typeB etc.
  onChange=e => this.change(e)
/>

在您的更改句柄中获取自定义属性,并使用它将值添加到正确的数组中。

change = e => 

  // create a copy of  this.state.groups
  const copyGroups = JSON.parse(JSON.stringify(this.state.groups));

  // get data-group value
  const group = event.target.dataset.group;

  if (!copyGroups[0][group]) 
    copyGroups[0][group] = []; // add type if it doesn't exists
  

  const groups = copyGroups[0][group];
  const index = this.findFieldIndex(groups, e.target.name);

  if (index < 0) 
    // if input doesn't exists add to the array
    copyGroups[0][group] = [...groups,  [e.target.name]: e.target.value ];
   else 
    // else update the value
    copyGroups[0][group][index][e.target.name] = e.target.value;
  

  this.setState( groups: copyGroups );
;

pre outline: 1px solid #ccc; padding: 5px; margin: 5px; 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>

<script type="text/babel">

function formatState(json) 
  if (typeof json != 'string') 
       json = JSON.stringify(json, undefined, 2);
  
  json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  return json.replace(/("(\\u[a-zA-Z0-9]4|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, (match) => match);


const Credentials = ( value ) => 
  return <pre>formatState(value)</pre>;
;

class App extends React.Component 
  state = 
    groups: [
      
        typeA: [],
        typeB: []
      
    ],
    credentials: false
  ;

  handleSubmit = event => 
    event.preventDefault();

    this.setState(
      credentials: true // display Credentials  component
    );
  ;

  // get the current input index in the array typeA | typeB
  findFieldIndex = (array, name) => 
    return array.findIndex(item => item[name] !== undefined);
  ;

    change = e => 

      // create a copy of  this.state.groups
      const copyGroups = JSON.parse(JSON.stringify(this.state.groups));

      // get data-group value
      const group = event.target.dataset.group;
      
      if (!copyGroups[0][group]) 
        copyGroups[0][group] = []; // add new type
      
      
      const groups = copyGroups[0][group];
      const index = this.findFieldIndex(groups, e.target.name);

      if (index < 0) 
        // if input doesn't exists add to the array
        copyGroups[0][group] = [...groups,  [e.target.name]: e.target.value ];
       else 
        // update the value
        copyGroups[0][group][index][e.target.name] = e.target.value;
      

      this.setState( groups: copyGroups );
    ;
    
 removeKey = (key) => 
    const temp = ...this.state;
    delete temp[key];
    return temp;
 

  render() 
    return (
      <div>
        <input
          type="text"
          name="col1"
          placeholder="Type A"
          data-group="typeA"
          onChange=e => this.change(e)
        />

        <input
          type="text"
          name="col2"
          placeholder="Type A"
          data-group="typeA"
          onChange=e => this.change(e)
        />

        <input
          type="text"
          name="col2"
          placeholder="Type B"
          data-group="typeB"
          onChange=e => this.change(e)
        />
        
        <input
          type="text"
          name="typec"
          placeholder="Type C | New Type"
          data-group="typeC"
          onChange=e => this.change(e)
        />
        
        <input
          type="text"
          name="typed"
          placeholder="Type D | New Type"
          data-group="typeD"
          onChange=e => this.change(e)
        />

        <button onClick=this.handleSubmit>Submit</button>
        this.state.credentials && (
          <Credentials value=JSON.stringify(this.removeKey('credentials'), undefined, 2) />
        )
      </div>
    );
  


ReactDOM.render(
    <App />,
    document.getElementById('root')
);
</script>

【讨论】:

天哪!凉爽的!谢谢!你能告诉我如何在不打印凭据的情况下打印出 JSON 对象:真的吗?我只是用它来打印出 JSON 对象 使用删除***.com/questions/3455405/… 好的,我明白了!谢谢 是的,我明白了!感谢您的帮助 嗨,Junis,我有一个问题,这只是对这个问题的延伸。我想知道是否有办法将输入值存储为数组(并且只是值)。假设,如果我有一个列的开始日期和结束日期:我想以数组的形式存储这些值。所以,我需要这样的输出:typeA: [ [col1value1, col1value2], [startdate, enddate]]。我知道这很复杂,但我的输出应该是这样的。没关系,即使我实际上没有将它存储在数组中

以上是关于如何将用户输入的输入保存为 React 中的数组状态的主要内容,如果未能解决你的问题,请参考以下文章

如何在隐藏输入字段中保存数组的值,然后再将其替换为新数组

react 中select添加一个删除第一个

如何将文本输入保存为 HTML 和 Django 中的文件

如何将信息作为数组python保存到json

具有数百个输入的巨大 React 状态数组,状态变化缓慢 onChange

REACT数组是真还是假输入?