Как обновить вложенные свойства без переопределения в неизменяемой функции Javascript - PullRequest
0 голосов
/ 01 сентября 2018

Я хочу знать, как я могу вернуть неизменный объект из функции (редуктор в реакции, но это не очень важно), чтобы объединить массив объектов (state) с другим объектом payload, который имеет вложенный объект subResults. Я в основном хочу вернуть состояние с помощью 2 записей ниже, но первая запись будет иметь вспомогательное свойство с именем subNodes, потому что state.results[0].name === payload[0].name

  state = {results:[
    {name:'name 1', description: 'I am a description'},
    {name:'name 2', description: 'I am a second description'}
    ]};



  payload = {results: [ {name:'name 1', subResults:{type:'whatever'} }]};

Это работает, если я позвоню:

{
   ...state,
   results: {
   ...state.results,
   ...payload.results[0]
   }
}

Проблема здесь в том, что я теряю свойство 'description', поскольку объект полезной нагрузки не имеет 'description' и переопределяет объект состояния. Я хочу сохранить объект состояния как есть и добавить только «subResults». Я также жестко программирую индекс [0], в то время как я хотел бы использовать свойство name для переопределения, как я упоминал выше.

У кого-нибудь есть идеи?

1 Ответ

0 голосов
/ 01 сентября 2018

Результатом является массив объектов, поэтому вам придется перебирать значения, также, если вы хотите объединить значение, если имя совпадает, пара функций массива может быть полезна

const state = {
  results: [
    { name: 'name 1', description: 'I am a description' },
    { name: 'name 2', description: 'I am a second description' },
  ],
}

const payload = {
  results: [
    { name: 'name 1', subResults: { type: 'whatever' } },
    { name: 'name 3', description: 'third one' },
  ],
}

function merge(state, payload) {
  return {
    ...state,
    ...payload,
    results: payload.results.reduce((newResults, newItem) => {
      // if item doesn't exist on the state, we add it
      if (!newResults.some(item => newItem.name === item.name)) {
        return [...newResults, newItem]
      }

      // otherwise, we merge it with the payload item information
      return newResults.map(item => {
        if (item.name === newItem.name) {
          return {
            ...item,
            ...newItem,
          }
        }

        return item
      })
    }, state.results),
  }
}

const newState = merge(state, payload)

console.log(newState)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...