#javascript #reactjs
#javascript #reactjs
Вопрос:
У меня есть функциональный Item
компонент, который использует React.memo
. Компонент отображает несколько разных полей ввода. Я пытаюсь обновить значение состояния для измененного, Item
но я не уверен, как это сделать без изменения или изменения текущего состояния, поскольку моя первоначальная реализация вызвала nextProps
и prevProps
для React.memo
того, чтобы быть одинаковым.
Вот мой обработчик в родительском компоненте контейнера:
handleItemChange = (item, event, index) => {
item[event.target.name] = event.target.value;
this.setState({
job: this.state.job
})
}
Мое состояние выглядит примерно так:
this.state = {
job: {
items: [{id: 1, quantity: 3, name: "test"}, {id: 2, quantity: 1, name: "test 2"}, {id: 3, quantity: 1, name: "test 3"}]
}
}
В моем компоненте формы я отображаю список Items
, подобный этому:
{this.props.job.items.map((i, index) => (
<Item key={i.id} handleItemChange={this.props.handleItemChange} item={i} index={index} />
))}
Затем в моем Item
компоненте (который запоминается) Я визуализирую поля ввода и вызываю обработчик:
function areEqual(prevProps, nextProps) {
console.log(prevProps.job_item.quantity)
console.log(nextProps.job_item.quantity)
return true
};
const Item = React.memo(props => {
return (
<Grid container spacing={3}>
<Grid item xs={1}>
<FormControl>
<TextField
name="quantity"
value={props.item.quantity}
label="quantity"
variant="outlined"
type="number"
onChange={e => props.handleItemChange(props.item, e, props.index)}
InputLabelProps={{
shrink: true,
}}
/>
</FormControl>
</Grid>
</Grid>
)
}, areEqual);
export default Item;
В этом текущем коде оба объекта prop areEqual
содержат одинаковые значения, и я считаю, что это связано с тем, что я изменяю item
непосредственно в handleItemChange
обработчике, но я не уверен, как изменить значение элемента, не ссылаясь на него напрямую. Я посмотрел на создание глубокой копии объекта массива, но я не уверен, как это сделать. Я также передаю значение индекса, поэтому this.state.job.items[index]
для моего случая возможна ссылка.
Комментарии:
1. пожалуйста, приходите с рабочим фрагментом, если у вас есть фрагмент, который четко показывает вашу проблему, он решит вашу проблему намного быстрее, чем без фрагмента
Ответ №1:
Может быть, это работает?
handleItemChange = (item, event, index) => {
// copy the state, since state should be immutable
let clonedJob = [...this.state.job];
// Find item in new state
let clonedItem = clonedJob.find(i => return i.id === item.id);
// Update that cloned item
clonedItem[event.target.name] = event.target.value;
// Update state
this.setState({
job: clonedJob
})
}