Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible bug when used with react-redux #60

Closed
danielepiccone opened this issue Apr 25, 2017 · 2 comments
Closed

Possible bug when used with react-redux #60

danielepiccone opened this issue Apr 25, 2017 · 2 comments

Comments

@danielepiccone
Copy link

When exporting a FormField decorated with connect(), somehow the form api breaks and the field does not re-render with the new values.

I believe this happens whatever higher order component is used to decorate the form, as long as this is using connect().

I have uploaded a sample app showing the bug here https://github.com/dpiccone/react-form-redux-bug

@danielepiccone
Copy link
Author

It turns out the problem is solved by passing { pure: false } as an option to connect() since redux assumes a component to receive updates either from props or from the store.

Alternatively you could use something like this, by connecting the component that receives the formAPI inside the FormField

import React from 'react';
import { FormField } from 'react-form';
import { connect } from 'react-redux';

function FormInput({ foobar, getValue, setValue }) {
  const value = getValue() || 0;
  const onClick = () => {
    setValue(value + 1);
  }

  return (
    <div>
      <p>click me</p>
      <p>{foobar}</p>
      <button onClick={onClick}>Clicked { value } times</button>
    </div>
  )
}

const mapStateToProps = state => {
  return {
    foobar: state.value
  }
};

FormInput = connect(mapStateToProps)(FormInput)

function Input(props) {
  return (
    <FormField field='foo'>
      {props => <FormInput {...props} />}
    </FormField>
  )
};

export default Input;

Or alternatively:

import React from 'react';
import { FormField } from 'react-form';
import { connect } from 'react-redux';
import { compose } from 'redux';

function withFormField(field) {
  return WrappedComponent => props => {
    return (
      <FormField field={field}>
        {(formApi) => {
          const allProps = {
            ...props,
            ...formApi
          };
          return (
            <WrappedComponent {...allProps} />
          )
        }}
      </FormField>
    )
  }
}

function Input({ foobar, getValue, setValue }) {
  const value = getValue() || 0;
  const onClick = () => {
    setValue(value + 1);
  }

  return (
    <div>
      <p>click me</p>
      <p>{foobar}</p>
      <button onClick={onClick}>Clicked { value } times</button>
    </div>
  )
}

const mapStateToProps = state => {
  return {
    foobar: state.value
  }
};

export default compose(
  withFormField('foo'),
  connect(mapStateToProps)
)(Input);

Is there any reason FormField is not provided as an higher order component but instead one should pass a function as the first child?

@tannerlinsley
Copy link
Collaborator

It was previously. Technically you could easily create your own HOC that utilizes the current form component implementation under the hood. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants