首页 > 解决方案 > 如何使用 redux 管理表单状态并以多步骤形式做出反应?

问题描述

我正在处理一个反应多步骤表单项目(结帐步骤)。当用户点击某个步骤(例如礼品包装部分)时,redux 状态将显示为 true,如果点击其他步骤的表单,则状态将为 false。我用它来控制是否在特定页面上显示详细信息。例如,当用户进入下一步并返回页面时,如果用户之前输入了礼物信息,则输入字段将被分配从 redux 存储到的值。

当用户停留在特定页面时,他们将能够成功地编辑和保存表单,(我使用redux创建了编辑和保存功能并将礼物信息保存到一个对象中)。但是,当用户进入下一步并单击返回某个页面时,该页面似乎重新呈现了一个新表单,并且 redux 存储仍然保存了我之前保存的信息,但是当我编辑并保存数据时,整个信息将被保存为一个新对象,该对象应用来自 redux 的新编辑和保存功能,因此存储数组将包含重复对象。

我想问一下这种情况有什么更好的解决方案?

onClickBack() {
    const { currentStep } = this.state;
    if (currentStep === 0) {
      this.setState({ showback: false});
    } else {
      if (currentStep === 3) {
        if(this.props.contacts != null){
          this.props.showDetail(); // state turns to true on step 3
        }
      } else {
        this.props.hideDetail();
      }
    }
  }

全局点击返回功能

saveGiftOption(e, index) {
      this.setState({ showhidedetail: !this.state.showhidedetail });
        e.preventDefault();
        let cartamount = 0;
        cartamount = parseInt(this.state.boxvalue.substring(1));
        let msg = {}; // the whole object will be saved into the redux array
        msg = {
            id: this.props.item.id,
            itemName: this.props.item.name,
            giftmessagevalue: this.state.giftmessagevalue,
            boxvalue: this.state.boxvalue,
            name: this.state.name,
            email: this.state.email,
            phone: this.state.phone,
            address: this.state.address,
            cartamount: cartamount,
        }
        Promise.all([
            this.props.addReducer(msg, index) // save action
        ]).then(() => {
            let payload = 0;
            payload = msg.cartamount;
            this.props.sumTotal(payload);
            this.props.sumArrayTotal(payload);
        });
    }

editGiftOption(e, index){
    this.setState({ showhidedetail: !this.state.showhidedetail });
    e.preventDefault();
    Promise.all([
        this.props.clearReducer(index) // clear action
    ]).then(() => {
        this.props.counter.counter -= this.props.counter.arr[index];
        this.props.clearTotal(index);
    });
}

步骤 3 表单上的保存并单击功能

switch (action.type) {
    case TYPE_ADD: // addReducer
      return [...state,
        Object.assign({}, action.msg)]
    case TYPE_CLEAR: // clearReducer
      return state.filter((data, i) => i !== action.id);
    default:
      return state
  }

添加和编辑减速器

contacts: [
    { id: '0c29c778', itemName: 'A item', giftmessagevalue: 'thankyou', ... },
    { id: '189377ad', itemName: 'B item', giftmessagevalue: 'test', ... },
    { id: '0c29c778', itemName: 'A item', giftmessagevalue: 'thankyou', ... },
    { id: '189377ad', itemName: 'B item', giftmessagevalue: 'test', ...}]
// first 2 object created when user stays on the certain page
// last 2 object created when user go to the next page  and go back to the certain page and edit the form

标签: javascriptreactjsreact-redux

解决方案


更好的方法是使用 redux-form ( https://redux-form.com/ ) 来管理 redux 中的表单状态。它允许将托管表单状态保存在 redux 存储中。如果用户在表单之间切换,则可以使用保存的信息重新初始化表单。

一般来说,这里的问题是状态没有正确恢复/设置。添加项目的减速器部分无法按预期工作:

返回 [...state, Object.assign({}, action.msg)]

可以看到,[{id: "aa"}, {id: "aa"}] 不能合并到 [{id: "aa"}] 中,因为它们是不同的对象。


推荐阅读