Передайте категорию и индекс предмета вашей функции handleChange
. Используйте эти индексы для обновления правильного элемента в массиве. Избегайте мутаций состояния, не делая
// state mutation
this.state.list[categoryIndex].fields[fieldIndex].amount = e.target.value
функция handleChange
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, добавить категорию и индекс в качестве реквизита.
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;
DEMO
const Item = ({ list, handleChange, categoryIndex, itemIndex, value }) => {
return (
handleChange(e, categoryIndex, itemIndex)}
/>
);
};
const Category = ({ name, list, handleChange, categoryIndex }) => {
return (
{name}
{list.fields.map((item, index) => (
))}
);
};
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 (
{this.state.list.map((item, index) => (
))}
{this.state.show &&
{JSON.stringify(this.state.list, null, 4)}
}
);
}
}
ReactDOM.render (
,
document.getElementById ( 'корень')
);