在 React 中处理复杂的多层表单数据 - 复选框

Handling Complex, Multi-Layer Form Data in React - Checkboxes

我正在使用 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
      });
    }
  }, []);

我已经尝试了很多不同的调度函数和缩减器函数的方法。我也尝试过理解 dispatch 和 reducer 函数之间的关系,但是我还没有找到任何可以帮助我理解当 reducer 的 action 参数是函数类型时发生了什么的东西。

我真的需要你的帮助来理解教程中复选框 dispatch/reducer 函数关系的情况。根据我的研究,这是唯一使用 reducer 的操作参数的构造函数类型来做出决策的实现(使用构造函数 === 函数和构造函数 === 对象)。据我了解,通常会改用 switch() 语句,这就是我在网上能找到的所有内容。

我还可以借助您的帮助了解如何让我的复选框正确更改其状态值。基本上,如何更改位于顶层以下的组件的状态?

在继续尝试更多想法后,我找到了一个我可以接受的解决方案。希望这个解决方案能帮助遇到同样问题的任何人。

我在 updateForm() 中更改了复选框部分,如下所示:

updateForm()

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

reducer()方法中我完全避免检查Function类型的构造函数,实现checkbox数据处理如下:

减速机()

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)
        })
      }
    }

我不是特别喜欢这个解决方案,因为它依赖于复选框的 checked 元素 属性。本教程使用 prevState 参数的实现是我的偏好,但显然我无法让它在我的情况下工作。

如果有人提出更好的解决方案,我会将其标记为答案。我也将不胜感激任何想法和意见。