0

我正在使用 React 钩子 useReducer 来处理复杂的多层表单数据。

我遵循了本教程的指导:https ://levelup.gitconnected.com/handling-complex-form-state-using-react-hooks-76ee7bc937 。

在本教程中,复选框状态设置在状态对象的顶层。但是,我的复选框位于顶层下方(确切地说是第 3 层)。问题是我的复选框组件将更改它的状态值,但会将自己置于顶层,而不是它应该位于第 3 级的位置。

Tutorial 的状态
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 参数是函数类型时发生的事情的东西。

我真的可以使用您的帮助来理解教程中的复选框调度/减速器函数关系发生了什么。根据我的研究,这是唯一使用 reducer 的 action 参数的构造函数类型来做出决策的实现(使用构造函数 === 函数和构造函数 === 对象)。据我了解,通常使用 switch() 语句代替,这就是我在网上能找到的全部内容。

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

4

1 回答 1

0

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

我更改了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参数的实现将是我的偏好,但显然我无法让它在我的情况下工作。

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

于 2020-04-07T18:35:53.917 回答