0

I got an issue may cause from react-boilerplate Or "redux-form/immutable", wish someone can help me out.

I tried to put some custom props into Form component and this will print out messages of error when submit.

Here is my code:

import React from 'react';
import { Form, Icon } from 'semantic-ui-react';
import { PropTypes } from 'prop-types';
import { Field, reduxForm, reset } from 'redux-form/immutable';
import { connect } from 'react-redux';

import { ReduxFormInput, ReduxFormCheckbox } from '../../components/ReduxFormInput';
import { signupSync, passStrength } from '../../components/Validate';
import StyledButton from '../../components/StyledButton';
import AcceptTerms from './acceptTerms';
import signupRequest from './actions';

class Signup extends React.Component {
  static propTypes = {
    handleSubmit: PropTypes.func.isRequired,
    submitting: PropTypes.bool.isRequired,
    signupRequest: PropTypes.func,
    signup: PropTypes.shape({
      requesting: PropTypes.bool,
      successful: PropTypes.bool,
      messages: PropTypes.array,
      errors: PropTypes.array,
    }),
  }

  submit(values, dispatch) {
    console.log(values);
    this.props.signupRequest(values); // will be undefined 'props' after submit
  }

  render() {
    const {
      handleSubmit,
      submitting,
      signup: {
        requesting,
        successful,
        messages,
        errors,
      },
    } = this.props;

    return (
      <Form onSubmit={handleSubmit(this.submit)} >
        <Form.Field>
          <Field
            type="text"
            name="accountName"
            component={ReduxFormInput}
            icon="user outline"
            label="Tên tài khoản"
            placeholder="Tên tài khoản của bạn"
          />
        </Form.Field>
        <Form.Field >
          <Field
            type="email"
            name="email"
            component={ReduxFormInput}
            icon="mail outline"
            label="Email"
            placeholder="Email của bạn"
          />
        </Form.Field>
        <Form.Field required >
          <Field
            type="password"
            name="password"
            component={ReduxFormInput}
            icon="lock"
            label="Mật khẩu"
            placeholder="Nhập mật khẩu"
            warn={passStrength}
          />
        </Form.Field>
        <Form.Field required >
          <Field
            type="password"
            name="confirmPassword"
            component={ReduxFormInput}
            icon="lock"
            label="Xác nhận Mật khẩu"
            placeholder="Xác nhận lại mật khẩu"
          />
        </Form.Field>
        <Form.Field>
          <Field
            defaultChecked
            type="checkbox"
            name="confirm"
            checkboxLabel="Tôi muốn nhận thông tin thông qua email, SMS, hoặc điện thoại."
            component={ReduxFormCheckbox}
          />
        </Form.Field>
        {AcceptTerms}
        <div>
          <StyledButton primary fluid type="submit" disabled={submitting} >
            <Icon name="add user" />
            Đăng ký tài khoản
          </StyledButton>
        </div>
      </Form>
    );
  }
}

const mapStateToProps = (state) => ({
  signup: state.signup,
});

const connected = connect(mapStateToProps, { signupRequest })(Signup);

const formed = reduxForm({
  form: 'signup',
  validate: signupSync,
  onSubmitSuccess: afterSubmit,
})(connected);

const afterSubmit = (result, dispatch) => dispatch(reset('signup'));

export default formed;

My reducer

import { SubmissionError } from 'redux-form/immutable';
import {
  SIGNUP_REQUESTING,
  SIGNUP_SUCCESS,
  SIGNUP_ERROR,
} from './constants';

const initialState = {
  requesting: false,
  successful: false,
  errors: [],
  messages: [],
};

const reducer = function signupReducer(state = initialState, action) {
  switch (action.type) {
    case SIGNUP_REQUESTING:
      return {
        requesting: true,
        successful: false,
        errors: [],
        messages: [{
          body: 'Signing up...',
          time: new Date(),
        }],
      };

    case SIGNUP_SUCCESS:
      return {
        requesting: false,
        successful: true,
        errors: [],
        messages: [{
          body: `Successfully created account for ${action.response.email}`,
          time: new Date(),
        }],
      };

    case SIGNUP_ERROR:
      return {
        requesting: false,
        successful: false,
        messages: [],
        errors: new SubmissionError({
          email: 'failed',
          _error: 'failed',
        }),
      };

    default:
      return state;
  }
};

export default reducer;

Inject reducer on routes.js

...
{
      path: '/signup',
      name: 'signup',
      getComponent(nextState, cb) {
        const importModules = Promise.all([
          import('containers/SignupPage/reducer'),
          import('containers/SignupPage/sagas'),
          import('containers/SignupPage'),
        ]);

        const renderRoute = loadModule(cb);

        importModules.then(([reducer, sagas, component]) => {
          injectReducer('signup', reducer.default);
          injectSagas(sagas.default);
          renderRoute(component);
        });
      },
    }
...

Then I got an error screen like this.

TypeError: Cannot read property 'requesting' of undefined
Signup.render
/Users/son/Desktop/we-mak/app/containers/SignupPage/signupForm.js
Signup.tryRender
http://localhost:3000/main.js:1388:1
Signup.proxiedMethod
http://localhost:3000/main.js:1356:1
eval
webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:796:21
measureLifeCyclePerf
webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:75:12
ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext
webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:795:25
ReactCompositeComponentWrapper._renderValidatedComponent
webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:822:32
ReactCompositeComponentWrapper._updateRenderedComponent
webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:746:36
ReactCompositeComponentWrapper._performComponentUpdate
webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:724:10
ReactCompositeComponentWrapper.updateComponent
webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:645:12

I notice that react-boilerplate doesn't use react-hot-loader so I guessed it may cause from boilerplate, but I don't have enough webpack experience to config it.

Son Dang
  • 153
  • 2
  • 11

1 Answers1

0

This error message means your signup property is undefined, which may happen if your state does not have signup property or that property is undefined. Have a look at your reducer.

Deividas
  • 6,437
  • 2
  • 26
  • 27