gpt4 book ai didi

javascript - 如何设置映射输入的嵌套 JSON 数组对象的状态

转载 作者:行者123 更新时间:2023-11-30 06:15:20 24 4
gpt4 key购买 nike

我有一个包含多个类别的 JSON 文件,每个类别都有一个名称以及一组具有自己的名称和值的输入字段。

如何使用 setState 更新每个 onChange 的值字段?类别和字段使用 map() 呈现。

我可以在没有嵌套字段的情况下使它工作,但不能。感谢任何帮助。

JSON 文件

[{
"catName": "Category 1",
"fields": [
{
"name": "field 1",
"amount": "0"
},
{
"name": "field 2",
"amount": "0"
}
]
},
{
"catName": "Category 2",
"fields": [
{
"name": "field 1",
"amount": "0"
},
{
"name": "field 2",
"amount": "0"
}
}]

主程序

import React, { Component } from "react";
import Category from "./Category";
import sampleData from "./sampleData";

class Main extends Component {
constructor(props) {
super(props);
this.state = {
list: sampleData
};
}

handleChange = e => {
this.setState({ ??? });
};

render() {
return (
<div>
{this.state.list.map(item => (
<Category
id={item.catName}
name={item.catName}
key={item.catName}
list={item}
handleChange={this.handleChange}
/>
))}
</div>
);
}
}

export default Main;

分类.js

import React from "react";
import Item from "./Item";

const Category = ({ name, list, handleChange }) => {
return (
<div className="section">
<h3>{name}</h3>
{list.fields.map(item => (
<Item
id={item.name}
name={item.name}
key={item.name}
list={item}
handleChange={handleChange}
/>
))}
</div>
);
};

export default Category;

项目.js

import React from "react";

const Item = ({ list, handleChange }) => {
return (
<div className="item">
<label className="label">{list.name}</label>
<input
name={list.name}
id={list.name}
className="input"
type="text"
onChange={handleChange}
value={list.amount}
/>
</div>
);
};

export default Item;

最佳答案

将类别和项目索引传递给您的 handleChange 函数。使用这些索引更新数组中的正确项。通过不做来避免状态突变

// state mutation
this.state.list[categoryIndex].fields[fieldIndex].amount = e.target.value

处理变化函数

handleChange = (e, categoryIndex, itemIndex) => {

const { list } = this.state;

const fields = [...list[categoryIndex].fields.slice(0, itemIndex),
Object.assign({}, list[categoryIndex].fields[itemIndex], { amount: e.target.value }),
...list[categoryIndex].fields.slice(itemIndex + 1)
]


this.setState({
list: [...list.slice(0, categoryIndex),
Object.assign({}, list[categoryIndex], { fields }),
...list.slice(categoryIndex + 1)
]
})
}

Item 组件,添加 category 和 filed index 作为 props。

import React from "react";

const Item = ({ list, handleChange, categoryIndex, itemIndex, value }) => {
return (
<div className="item">
<label className="label">{list.name}</label>
<input
name={list.name}
id={list.name}
className="input"
type="text"
value={value}
onChange={(e) => handleChange(e, categoryIndex, itemIndex)}
/>
</div>
);
};

export default Item;

类别组件

import React from "react";
import Item from "./Item";

const Category = ({ name, list, handleChange, categoryIndex }) => {
return (
<div className="section">
<h3>{name}</h3>
{list.fields.map((item, index) => (
<Item
id={item.name}
name={item.name}
key={item.name}
list={item}
categoryIndex={categoryIndex}
itemIndex={index}
value={item.amount}
handleChange={handleChange}
/>
))}
</div>
);
};

export default Category;

演示

<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">

const Item = ({ list, handleChange, categoryIndex, itemIndex, value }) => {
return (
<div className="item">
<label className="label">{list.name}</label>
<input
name={list.name}
id={list.name}
className="input"
type="text"
value={value}
onChange={(e) => handleChange(e, categoryIndex, itemIndex)}
/>
</div>
);
};

const Category = ({ name, list, handleChange, categoryIndex }) => {
return (
<div className="section">
<h3>{name}</h3>
{list.fields.map((item, index) => (
<Item
id={item.name}
name={item.name}
key={item.name}
list={item}
categoryIndex={categoryIndex}
itemIndex={index}
value={item.amount}
handleChange={handleChange}
/>
))}
</div>
);
};

class App extends React.Component {
constructor() {
super();
this.state = {
name: 'React',
show: false,
list: [
{
"catName": "Category 1",
"fields": [
{
"name": "field 1",
"amount": "0"
},
{
"name": "field 2",
"amount": "0"
}
]
},
{
"catName": "Category 2",
"fields": [
{
"name": "field 1",
"amount": "0"
},
{
"name": "field 2",
"amount": "0"
}
]
}
]
};
}

handleChange = (e, categoryIndex, itemIndex) => {

const { list } = this.state;

const fields = [...list[categoryIndex].fields.slice(0, itemIndex),
Object.assign({}, list[categoryIndex].fields[itemIndex], { amount: e.target.value }),
...list[categoryIndex].fields.slice(itemIndex + 1)
]


this.setState({
list: [...list.slice(0, categoryIndex),
Object.assign({}, list[categoryIndex], { fields }),
...list.slice(categoryIndex + 1)
]
})
}

show = () => {
this.setState({
show: true
})
}

render() {
return (
<div>
{this.state.list.map((item, index) => (
<Category
id={item.catName}
name={item.catName}
key={item.catName}
categoryIndex={index}
list={item}
handleChange={this.handleChange}
/>
))}
<br />
<button onClick={this.show}>Show changes</button>
{this.state.show &&
<pre>
{JSON.stringify(this.state.list, null, 4)}
</pre>
}
</div>
);
}
}

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

关于javascript - 如何设置映射输入的嵌套 JSON 数组对象的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56514469/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com