Обработка сложных, многоуровневых данных форм в React - флажки

Я использую перехватчик React useReducer для обработки сложных, многоуровневых данных формы в состоянии.

Я следовал указаниям из этого руководства: https://levelup.gitconnected.com/handling-complex-form-state-using-react-hooks-76ee7bc937.

В учебнике состояние флажка устанавливается на верхнем уровне объекта состояния. Однако флажок "Мой" находится под верхним слоем (точнее, уровнем 3). Проблема в том, что мой компонент флажка изменит свое значение состояния, но разместится на верхнем уровне, а не там, где он должен быть на уровне 3.

Состояние
учебника isMember находится на верхнем уровне

const initialState = {
  firstName: "",
  lastName: "",
  address: {
    addressLine1: "",
    addressLine2: "",
    pinCode: ""
  },
  isMember: false
};

Мое состояние
включено ниже верхнего уровня

const initState = 
{
  radio:{
    tx: {
      name:'',
      enabled:'',//THIS IS WHERE THE STATE SHOULD CHANGE.
      parameters:{
        frequency:'',
        bandwidth:'', 
      },
    },
  }
  //BUT THIS IS WHERE IT IS GETTING SET.
};

Ниже представлена ​​моя реализация функции updateForm:

const updateForm = React.useCallback(({ target: { value, name, type } }) => {
    const updatePath = name.split(".");
    console.log("updateForm | updatePath: ", updatePath);

    // Set top-level key-pairs.
    // Just need specific component & value to update.
    if (updatePath.length === 1) {
      const [id] = updatePath;

      dispatch({
        type: "TF",
        [id]: value
      });
    }

    // Set key-pairs that're below top-level.
    // Need "path" to component ('name') & value to update.
    // More condensed solution, rather than multiple if(length === 3,4,...).
    if (updatePath.length >= 2) {
      // Set checkboxes.
      if (type === "checkbox") {
        let elem = updatePath[updatePath.length - 1];

        dispatch(prevState => ({
          [name]: !prevState[name]
        }));
        return;
      }

      dispatch({
        _path: updatePath,
        _value: value
      });
    }
  }, []);

Я пробовал много разных подходов к функции диспетчеризации и функции редуктора. Я также попытался понять взаимосвязь между функциями диспетчеризации и редуктора, но я не нашел ничего, что помогло бы мне понять, что происходит, когда параметр действия редуктора имеет тип function.

Мне действительно нужна ваша помощь, чтобы понять, что происходит с отношением функции диспетчеризации и редуктора флажка в руководстве. Из того, что я исследовал, это единственная реализация, которая использует тип конструктора параметра действия редуктора для принятия решений (с помощью конструктора === Function & constructor === Object). Насколько я понимаю, обычно вместо этого используется оператор switch(), и это все, что мне удалось найти в Интернете.

Я также мог бы использовать вашу помощь в понимании того, как заставить мой флажок правильно изменять его значение в состоянии. В принципе, как мне изменить состояние этого компонента, который находится ниже верхнего слоя?

1 ответ

Решение

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

Я изменил раздел флажков в моем updateForm() следующим образом:

updateForm()

// Set checkboxes.
      if (type === "checkbox"){
        dispatch({
          _path: updatePath,
          _value: checked,
          _type: type
        });
        return;
      }

В методе reducer() я полностью избегаю проверки конструктора типа Function и реализую обработку данных флажка следующим образом:

редуктор ()

if(has(updateArg, "_path") && has(updateArg, "_value") && has(updateArg, "_type")){
      const { _path, _value, _type } = updateArg;

      if(_type === "checkbox"){
        return produce(state, draft => {
          set(draft, _path, _value)
        })
      }
    }

Мне не особенно нравится это решение из-за того, что я полагаюсь на свойство отмеченного флажка элемента. Я бы предпочел реализовать в учебнике использование аргумента prevState, но, очевидно, я не смог заставить его работать в моих обстоятельствах.

Если кто-то придумает лучшее решение, я отмечу это как ответ. Буду признателен за любые мысли и мнения.

Другие вопросы по тегам