如何将用户输入的输入保存为 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, '&').replace(/</g, '<').replace(/>/g, '>');
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 中的数组状态的主要内容,如果未能解决你的问题,请参考以下文章