Как я могу получить текущее значение входа, который является частью массива объектов? - PullRequest
0 голосов
/ 07 мая 2019

Итак, я пытаюсь заполнить массив данными.Я сталкиваюсь с одной проблемой.

1 - я пытаюсь найти index для каждого правильного ключа в массиве объектов.Но я получаю сообщение об ошибке после добавления нового ввода.Да, я тоже добавляю входные данные динамически.

Входные данные добавляются хорошо.

Это, например, то, как должны выглядеть данные перед отправкой на сервер.Вот как должен выглядеть конечный объект:

{
  "previous_investments" : [
      {"name" : "A Name", "amount" : 10000},
      {"name" : "Some Name", "amount" : 35000}
  ]
}

Кажется, что это легко, но мне трудно.

Вот так выглядит мой основной компонент:

const PreviousInvestments = ({
  startupFourthStepForm,
  previousInvestmentsInputs,
  startupFourthStepFormActionHandler,
  previousInvestmentsInputsActionHandler,
}) => {
  const handleMoreInputs = async () => {
    await startupFourthStepFormActionHandler(
      startupFourthStepForm.previous_investments.push({
        name: '',
        amount: undefined,
      }),
    );
    await previousInvestmentsInputsActionHandler(
      `previous_investments-${previousInvestmentsInputs.length}`,
    );
  };

  return (
    <div className="previous-investments-inputs">
      <p>Previous Investments</p>
      {previousInvestmentsInputs.map((input, index) => (
        <div key={input}>
          <FormField
            controlId={`name-${index}`}
            onChange={e => {
              startupFourthStepFormActionHandler({
                // HERE IS WHERE I THINK I AM PROBABLY FAILING
                previous_investments: [{ name: e.currentTarget.value }],
              });
            }}
            value={startupFourthStepForm.previous_investments[index].name}
          />
        </div>
      ))}      
      <Button onClick={() => handleMoreInputs()}>
        + Add more
      </Button>    
    </div>
  );
};

export default compose(
  connect(
    store => ({
      startupFourthStepForm:
        store.startupApplicationReducer.startupFourthStepForm,
      previousInvestmentsInputs:
        store.startupApplicationReducer.previousInvestmentsInputs,
    }),
    dispatch => ({
      previousInvestmentsInputsActionHandler: name => {
        dispatch(previousInvestmentsInputsAction(name));
      },
      startupFourthStepFormActionHandler: value => {
        dispatch(startupFourthStepFormAction(value));
      },
    }),
  ),
)(PreviousInvestments);

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

      <Button onClick={() => handleMoreInputs()}>
        + Add more
      </Button>  

Это редуктор:

const initialState = {
  startupFourthStepForm: {
    previous_investments: [{ name: '', amount: undefined }],
  },

  previousInvestmentsInputs: ['previous_investments-0'],
}

const handlers = {
  [ActionTypes.STARTUP_FOURTH_STEP_FORM](state, action) {
    return {
      ...state,
      startupFourthStepForm: {
        ...state.startupFourthStepForm,
        ...action.payload.startupFourthStepForm,
      },
    };
  },

  [ActionTypes.PREVIOUS_INVESTMENTS_INPUTS](state, action) {
    return {
      ...state,
      previousInvestmentsInputs: [
        ...state.previousInvestmentsInputs,
        action.payload.previousInvestmentsInputs,
      ],
    };
  },
}

Самое смешное, что я могу набрать первый ввод, и все идет хорошо.Но как только я добавляю новый вход, второй, я получаю эту ошибку:

TypeError: Невозможно прочитать свойство 'name' из undefined

43 |controlId = {startupFourthStepForm.previous_investments [index] .name}

Ву, что, по вашему мнению, мне не хватает?

1 Ответ

1 голос
/ 07 мая 2019

Обработчик для ActionTypes.STARTUP_FOURTH_STEP_FORM определен так, чтобы вызываться с объектом для startupFourthStepForm в полезной нагрузке и эффективно заменять его.

Когда этот обработчик вызывается, вы должны убедиться, что он вызывается сПоле previous_investments объединено с новым значением

startupFourthStepFormActionHandler({
   ...startupFourthStepForm,
   previous_investments: [
     ...startupFourthStepForm.previous_investments.slice(0, index),
     {
       ...startupFourthStepForm.previous_investments[index],
       name: e.currentTarget.value
     },
     ...startupFourthStepForm.previous_investments.slice(index+1,)
   ],
});

Я предлагаю выполнить рефакторинг для переноса этого обновления состояния из обработчика в редуктор, чтобы обновления хранилища отражались в совмещенном месте.Это можно сделать, передав index элемента в previous_investments как часть полезной нагрузки для действия ActionTypes.STARTUP_FOURTH_STEP_FORM.

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