React JS - Добавление нескольких дочерних узлов к одному узлу без перезаписи текущего содержимого - PullRequest
1 голос
/ 26 мая 2020

См. Код ниже. В операторе возврата я пытаюсь добавить компоненты со структурой:

  • входы
    • inputId
      • rowId
        1. значение
        2. isValid
      • rowId
        1. значение
        2. isValid
    • inputId
      • rowId
        1. значение
        2. isValid
      • rowId
        1. value
        2. isValid

Однако, когда я пытаюсь использовать синтаксис распространения для сохранения состояния и просто добавлять узлы в состояние, я не могу загрузить уже определенные компоненты rowId для указанного c inputId, потому что синтаксис, подобный следующему, не работает ...state.inputs.[action.inputId].rowId.

В настоящее время происходит то, что «состояние» всегда содержит только один компонент rowId (последний one), потому что он перезаписывает предыдущие, потому что я не могу правильно использовать синтаксис распространения для сохранения исходного состояния.

Код:

const formReducer = (state, action) => {
  switch (action.type) {
    case 'INPUT_CHANGE':
      let formIsValid = true;
      for (const inputId in state.inputs) {
        if (inputId === action.inputId) {
          formIsValid = formIsValid && action.isValid;
        } else {
          formIsValid = formIsValid && state.inputs[inputId].isValid;
        }
      }
      return {
        ...state,
        inputs: {
          ...state.inputs,
          [action.inputId]: { 
              [action.rowId]: {     //This is the problematic line ... I would like to execute ' ...state.inputs.[action.inputId].rowId ' before this line
                value: action.value, 
                isValid: action.isValid 
              }   
          }
        },
        isValid: formIsValid
      };
    default:
      return state;
  }
};

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Ваш код (logi c) действительно трудно читать.

В любом случае, похоже, вы упустили использование ключа объекта в качестве переменной.

Используйте:

...state.inputs[action.inputId].rowId 

Вместо этого:

...state.inputs.[action.inputId].rowId 
0 голосов
/ 26 мая 2020

Если я правильно понял, вам нужно ...state.inputs[action.inputId]:

return {
    ...state,
    inputs: {
        ...state.inputs,
        [action.inputId]: { 
            ...state.inputs[action.inputId],
            [action.rowId]: {     
                // Another example: if you would also need to merge here with the previous state, you would need:               
                // ...(state.inputs[action.inputId] ? state.inputs[action.inputId][action.rowId] : [],
                // OR if optional chaining operator is supported:
                // ...state.inputs[action.inputId]?.[action.inputId],
                value: action.value, 
                isValid: action.isValid 
            }   
        }
    },
    isValid: formIsValid
};

(надеюсь, синтаксической ошибки нет).

Или используйте что-то вроде Immer , если вы хотите большей гибкости / читаемости при работе с неизменяемыми данными.

...