如何将react-credit-cards与redux-form向导形式集成在一起

时间:2017-08-01 18:20:35

标签: reactjs react-native redux credit-card redux-form

Redux-form Wizard http://redux-form.com/6.7.0/examples/wizard/适用于示例中的标准控件。我试图集成更复杂的控件,例如react-credit-cards enter link description here,并且在将状态值传递给向量REDx状态onSubmit时遇到问题。

向导表单在编译表单数据列表时非常有用,OnSubmit会发回存储在redux中的捕获表单数据的完整列表。此类表格对于进行注册,付款信息和调查等非常有用。

目前的行为?

用例是使用Wizard示例,并在其中一个向导页面捆绑带信用卡信息。信用卡控件的封装方式与redux-form示例中提供的renderField类相同。

渲染类调用信用卡控件并创建4个输入控件,以将信用卡号的值传递到控件中以绘制信用卡,同时将数据复制到组件状态。这完全基于react-credit-cards卡团队提供的演示代码。

  render() {
    const { name, number, expiry, cvc, focused } = this.state;
    return (
      <div className="creditCardContainer">
        <h1>React Credit Cards</h1>
        <div className="creditCardForm">
          <CreditCards
            number={number}
            name={name}
            expiry={expiry}
            cvc={cvc}
            focused={focused}
            callback={this.handleCallback}
          />
          <form>
            <div>
              <input
                type="tel"
                name="number"
                placeholder="Card Number"
                onKeyUp={this.handleInputChange}
                onFocus={this.handleInputFocus}
              />
              <div>E.g.: 49..., 51..., 36..., 37...</div>
            </div>
            <div>
              <input
                type="text"
                name="name"
                placeholder="Name"
                onKeyUp={this.handleInputChange}
                onFocus={this.handleInputFocus}
              />
            </div>
            <div>
              <input
                type="tel"
                name="expiry"
                placeholder="Valid Thru"
                onKeyUp={this.handleInputChange}
                onFocus={this.handleInputFocus}
              />
              <input
                type="tel"
                name="cvc"
                placeholder="CVC"
                onKeyUp={this.handleInputChange}
                onFocus={this.handleInputFocus}
              />
            </div>
          </form>
        </div>
      </div>
    );
  }

预期的行为是什么?

需要一些关于如何将值从renderCreditCard组件状态复制到Wizard form redux状态的建议。

目前在向导表单的onSubmit

class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2> {COMPANY} - Sign up form</h2>
        </div>
        <p className="App-intro">
        </p>
        **<WizardForm onSubmit={showResults} />**
        <div className="App-footer">
          <div>Icons made by <a href="http://www.freepik.com" title="Freepik">Freepik</a> from <a href="http://www.flaticon.com" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0">CC 3.0 BY</a></div>
        </div>
      </div>
    );
  }
}

回调函数中的redux数据返回不包含注入Field的renderCreditCard组件的数据。

const showResults = values => {

  // append primary key to data
  values["id"] = _.uniqueId();
  values["number"] <- this is currently undefined
  values["names"] <- this is currently undefined
  values["expiry"] <- this is currently undefined
  values["cvc"] <- this is currently undefined
  ...
  });

当一切正常时,理想情况下,回调中的值应从向导表单中返回数字,名称,到期日和cvc。

我尝试了几种方法,包括将renderCreditCard.js输入控件转换为带有component =“renderField”的Field,但没有成功。

有没有人试图将react-credit-cards集成到redux-form中?特别是在向导形式模式?有什么方法可以将信用卡组件状态传播回redux-form?

问题是以redux-form issue

跟踪

1 个答案:

答案 0 :(得分:1)

您正在寻找的内容可分为三个问题

  1. 如何将信用卡信息的输入连接到redux-form
  2. 如何访问redux-form存储的信用卡信息?
  3. 如何将该数据提供给react-credit-cards
  4. 提供的组件

    让我们一块一块地解决这些问题:

    将信用卡信息的输入连接到redux-form

    此步骤很简单,只需使用redux-form提供的Field组件。

    // naturally this is within a component that is wrapped with `reduxForm`
    render (
      <form>
        <div>
          <Field
            component="input"
            name="number"
            normalize={ this.ensureCcNumberFormatting }
            placeholder="Card number"
            type="tel"
            onFocus={ this.handleInputFocus }
          />
        </div>
    
        <div>
          <Field
            component="input"
            name="name"
            normalize={ this.ensureCcNameFormatting }
            placeholder="Name"
            type="text"
            onFocus={ this.handleInputFocus }
          />
        </div>
    
        <div>
          <Field
            component="input"
            name="expiry"
            normalize={ this.ensureCcExpiryFormatting }
            placeholder="Valid Thru"
            type="tel"
            onFocus={ this.handleInputFocus }
          />
        </div>
    
        <div>
          <Field
            component="input"
            name="cvc"
            normalize={ this.ensureCcCvcFormatting }
            placeholder="CVC"
            type="tel"
            onFocus={ this.handleInputFocus }
          />
        </div>
      </form>
    )
    

    现在,字段numbernameexpirycvc以及相关的用户输入应存储在redux表单下的redux存储中。减速器。请注意,传递给normalize道具的函数与react-credit-cards示例中与the payment library的绑定功能相同:它们应该接受用户输入并格式化信用卡号并强制执行长度限制。有关normalize herehere的更多信息。

    另请注意,onBlur道具应传递与react-credit-cards示例中传递的类似函数。 redux-form不会向装饰组件注入一个prop,它提供有关选择哪个输入字段的信息,因此您需要自己维护此数据(参见this issue)。

    redux-form

    访问数据

    就像存储在redux商店中的任何内容一样,我建议使用react-redux and the connect decorator将商店中的值注入到组件中。令人高兴的是,redux-form还提供a nifty formValueSelector用于此目的。

    const selector = formValueSelector('MyFormName')
    
    // returns `{ number: '<data>', name: '<data>', expiry: <data>, cvc: '<data>' }`
    const mapStateToProps = state => selector(state, 'number', 'name', 'expiry', 'cvc')
    

    现在,您的组件应该将信用卡信息作为道具提供。

    react-credit-cards

    向组件中注入必要的数据

    这很简单,只需从组件propsstate中提取必要的变量,然后将它们注入CreditCards组件。

    render() {
      const { number, name, expiry, cvc } = this.props
      const { focused } = this.state
    
      return (
        <form>
          <CreditCards
            number={number}
            name={name}
            expiry={expiry}
            cvc={cvc}
            focused={focused}
            callback={this.handleCallback}
          />
          { /* the fields from the first code example down here */ }
        </form>
      )
    }
    

    希望这有帮助!