rc-form@2.4.12

React High Order Form Component

/* eslint react/no-multi-comp:0, no-console:0, react/prefer-stateless-function:0 */

import { createForm, createFormField, formShape } from 'rc-form';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { combineReducers, createStore } from 'redux';
import { Provider, connect } from 'react-redux';
import ReactDOM from 'react-dom';
import { regionStyle, errorStyle } from './styles';

function form(state = {
  email: {
    value: 'x@gmail.com',
  },
}, action) {
  switch (action.type) {
    case 'save_fields':
      return {
        ...state,
        ...action.payload,
      };
    default:
      return state;
  }
}

class Form extends Component {
  static propTypes = {
    form: formShape,
  }

  render() {
    const { getFieldProps, getFieldError } = this.props.form;
    const errors = getFieldError('email');
    return (<div style={ regionStyle }>
      <div>email:</div>
      <div>
        <input {...getFieldProps('email', {
          rules: [{
            type: 'email',
          }],
        })}
        /></div>
      <div style={errorStyle}>
        {(errors) ? errors.join(',') : null}
      </div>
    </div>);
  }
}

class Out extends React.Component {
  static propTypes = {
    email: PropTypes.object,
    dispatch: PropTypes.func,
  };
  setEmail = () => {
    this.props.dispatch({
      type: 'save_fields',
      payload: {
        email: {
          value: 'yiminghe@gmail.com',
        },
      },
    });
  }
  render() {
    const { email } = this.props;
    return (<div style={ regionStyle }>
      <div>
        email: {email && email.value}
      </div>
      <button onClick={this.setEmail}>set</button>
    </div>);
  }
}

Out = connect((state) => {
  return {
    email: state.form.email,
  };
})(Out);

const store = createStore(combineReducers({
  form,
}));

const NewForm = connect((state) => {
  return {
    formState: {
      email: state.form.email,
    },
  };
})(createForm({
  mapPropsToFields(props) {
    console.log('mapPropsToFields', props);
    return {
      email: createFormField(props.formState.email),
    };
  },
  onFieldsChange(props, fields) {
    console.log('onFieldsChange', fields);
    props.dispatch({
      type: 'save_fields',
      payload: fields,
    });
  },
})(Form));

class App extends React.Component {
  render() {
    return (<Provider store={store}>
      <div>
        <h2>integrate with redux</h2>
        <NewForm />
        <Out />
      </div>
    </Provider>);
  }
}

ReactDOM.render(<App />, document.getElementById('__react-content'));
Fork me on GitHub