Redux Form Usage

import React from 'react';
import { reduxForm } from 'redux-form'; 

function MyComponent() {
  // component
}

const formHook = reduxForm({
  form: 'FORM_NAME',
});

export default formHook(MyComponent);
  • Field
  • Fields
  • FieldArray
  • FormSection

Components

Selectors

  • formValueSelector
  • getFormValues

Actions

  • initialize
  • change
  • reset

Introduction

Form Nesting Problem

component A

component B

reduxForm({ form: 'FORM_NAME' })(A);
reduxForm({ form: 'FORM_NAME' })(B);

Form Nesting Problem

Why ?

  • Some part of Fields are represent for significant feature
  • Some input Field has complicated logic
  • Some input Field will affect other Fields 

EX: 會員資料、商品資訊、付款資訊

EX: 文字編輯器(array push, array pop)

EX: 縣市 => 鄉鎮 => 門市、品牌 => 型號 => 顏色

Form Nesting Solution

component A

component B

import React from 'react';
import { Field } from 'redux-form'; 

function B() {
  return (
    <Field
      name="name"
      component={Input} />
  );
}

export default B;

import BComponent from './B'; 

const FORM_NAME = 'FORM_NAME';

function A() {
  return (
    <BComponent />
  );
}

reduxForm({ form: FORM_NAME })(A);

Solution 0: Just put in different component    Σ( ° △ °)

Form Nesting Solution

component A

component B

export wrapFormInComponent(formName){
  return reduxForm({
    form: formName,
  })(B);
}
import { wrapFormInComponent } from './B'; 

const FORM_NAME = 'FORM_NAME';
const BComponent = wrapFormInComponent(FORM_NAME);

reduxForm({ form: FORM_NAME })(A);

Solution 1: Export function from children

Form Nesting Solution

Solution 1: Export function from children

=> Form still nested

Usage scenarios

  1. Component need some part of form value (display only)

=> 不在 child component 再綁一次 reduxForm,而只使用 redux connect

export wrapFormInComponent(formName){
  const selector = formValueSelector(formName);

  return connect(
    state => ({
      memberName: selector(state, 'name'),
    }),
  )(B);
}

2. Form fields are the same, but need to bind different form name

Form Nesting Solution

component A

component B

import React from 'react';
import { Field } from 'redux-form';

function B() {
  return (
    <Field
      name="name"
      component={Input} />
  );
}

export default B;
import BComponent from './B'; 

const FORM_NAME = 'FORM_NAME';

function A() {
  return (
    // some Fields
    <FormSection name="Member">
      <BComponent />
    </FormSection>
  );
}

reduxForm({ form: FORM_NAME })(A);

Solution 2: Use <FormSection>

Form Nesting Solution

Solution 2: Use <FormSection>

Usage scenarios

  1. Some part of Fields are represent for significant feature

Disadvantages

  • Data structure will be more complicated
  • FormSection name should be maintained
{
  "name": "國均"
}
{
  "Member": {
    "name": "國均"
  }
}

EX: 會員資料、商品資訊、付款資訊

Form Nesting Solution

component A

component B

import React from 'react';
import { Field } from 'redux-form';

function B({
  cityId,
  districtId,
}) {
  return (
    <>
      {cityId ? (
        <Field
          name="cityId"
          onChange={() => {
            districtId.input.onChange('-1');
          }}
          component={Input} />
      ) : null}
    </>
  );
}

export default B;
import BComponent from './B'; 

const FORM_NAME = 'FORM_NAME';

function A() {
  return (
    // some Fields
    <Fields
      names={[
        'cityId',
        'districtId',
      ]}
      component={BComponent} />
  );
}

reduxForm({ form: FORM_NAME })(A);

Solution 3: Use <Fields>

Form Nesting Solution

Solution 3: Use <Fields>

Usage scenarios

  1. Some input Field will affect other Fields 

Advantages

  • Avoid using redux-form actions (formValueSelector, change)
  • Field change won't cause other field re-render

FieldArray

Usage scenarios

Field value type is array

Advantages

Avoid using redux-form actions (arrayPush, arrayPop...etc)

Examples

Redux Form Usage

By Travor Lee

Redux Form Usage

  • 165