Мне было интересно, есть ли какая-либо документация или ссылка, которая могла бы помочь мне понять, как обновить состояние массива объектов (без дубликатов).
Мое состояние выглядит так:
accounts: [
{ name: ‘mike’ },
{ name: ‘tee’ },
{ name: ‘ralf’ },
{ name: ‘candy’ },
{ name: ‘bon’ },
{ name: ‘salm’ },
{ name: ‘shark’ },
{ name: ‘tof’ },
{ name: ‘hulk’ },
{ name: ‘zar’ },
{ name: ‘blake’ },
],
предстоящий массив выглядит так:
accounts: [
{ name: 'mike’, balance: ’1000’},
{ name: 'tee’, balance: ’235345’},
{ name: 'zar’, balance: ’3455’},
{ name: 'candy’, balance: ’567567’},
{ name: 'tee’, balance: ’8767’},
{ name: 'salm', balance: ’234’},
{ name: 'blake', balance: ’134’},
],
Таким образом, обновленное состояние setState будет выглядеть так:
accounts: [
{ name: 'mike’, balance: ’1000’},
{ name: 'tee’, balance: ’235345’},
{ name: ‘ralf’ },
{ name: 'candy’, balance: ’567567’},
{ name: ‘bon’ },
{ name: 'salm', balance: ’234’},
{ name: ‘shark’ },
{ name: ‘tof’ },
{ name: ‘hulk’ },
{ name: 'zar’, balance: ’3455’},
{ name: 'blake', balance: ’134’},
],
Я пробовал с prevState.accounts.concat(accounts), но он только добавляет дубликаты.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Найдите объект на основе условия, а затем обновите значения, где используйте метод Array#find для поиска элемента и метод Object.assign для копирования значений в существующий объект.
accounts.forEach( o => {
let oldObj = prevState.accounts.find(o1 => o1.name === o.name);
Object.assign(oldObj, o)
})
Окончательный код будет выглядеть так:
this.setState(prevState => {
newAccounts.forEach(o => {
let oldObj = prevState.accounts.find(o1 => o1.name === o.name);
Object.assign(oldObj, o)
})
return prevState.accounts
});
Решение Oneliner путем создания нового массива.
this.setState(prevState => newAccounts.map(o => Object.assign(prevState.accounts.find(o1 => o1.name === o.name), o)));
// if you don't want to mutate original object in previous state then
this.setState(prevState => newAccounts.map(o => Object.assign({}, prevState.accounts.find(o1 => o1.name === o.name), o)));
// or with ES6 spread syntax
this.setState(prevState => newAccounts.map(o => ({ ...prevState.accounts.find(o1 => o1.name === o.name), ...o }))));Я бы использовал {} в качестве первого аргумента, чтобы сделать его чистым.
@JonasWilms: зависит от его потребностей ... {...oldObj, ...o} или Object.assign({}, oldObj, o)
Большое спасибо. Это кажется полезным, но как мне использовать этот метод для setState?
@mediaroot this.setState(prevState => { newAccounts.forEach(o => { let oldObj = prevState.accounts.find(o1 => o1.name === o.name); Object.assign(oldObj, o) return prevState.accounts }) });
Удивительно. Большое спасибо.
Если ваши новые учетные записи состояний всегда будут подмножеством значений предыдущих учетных записей состояний. Вы можете использовать что-то вроде этого
this.state = {
accounts : [
{ name: 'mike' },
{ name: 'tee' },
{ name: 'ralf' },
{ name: 'candy' },
{ name: 'bon' },
{ name: 'salm' },
{ name: 'shark' },
{ name: 'tof' },
{ name: 'hulk' },
{ name: 'zar' },
{ name: 'blake' },
]
}
const newAccounts = [
{ name: 'mike', balance: 1000},
{ name: 'tee', balance: 235345},
{ name: 'zar', balance: 3455},
{ name: 'candy', balance: 567567},
{ name: 'tee', balance: 8767},
{ name: 'salm', balance: 234},
{ name: 'blake', balance: 134},
]
this.setState({accounts: this.state.accounts.map (x => ({...x, ...newAccounts.find(y => y.name === x.name)}))});
Вы можете использовать Массив.найти, чтобы найти значения старых учетных записей состояния в новых учетных записях, а затем использовать ... или Объект.назначить для объединения свойств.
Разве это не изменит объекты prevState?
Большое спасибо. Да, это всегда будет подмножество
нет, это не будет мутировать, потому что .map вернет новый массив, а я использую... для деструктуризации и возврата новых объектов для этого массива
Если у вашего
accountsнет повторяющихся имен, не будет ли логичнее, чтобы это был объект? Тогда это будет намного эффективнее.