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

[v8.1.0] initialValues are undefined at first render #4344

Open
jacekkolasa opened this issue Jan 2, 2019 · 22 comments
Open

[v8.1.0] initialValues are undefined at first render #4344

jacekkolasa opened this issue Jan 2, 2019 · 22 comments

Comments

@jacekkolasa
Copy link

Are you submitting a bug report or a feature request?

Bug Report

What is the current behavior?

When providing inivialValues, on first render the value specified in initialValues is undefined

What is the expected behavior?

In v7.4.2 the value passed as initialValue was available at first render. I couldn't find any information about it in changelog so i assume this should work as in v7.4.2.

Sandbox Link

i've created a simple component - reduxForm() is created using an initialValue, then it is passed to the component using connect() and formValueSelector. Observe the console.logs:
[email protected] https://codesandbox.io/s/54pn3nvv8n

firstname undefined
firstname john

[email protected] https://codesandbox.io/s/lrk4y97qw9

firstname john
firstname john

Is it a bug or is it now an expected behaviour?

Other information

here's the code (same as in codesandbox):

const valueSelector = formValueSelector("myform");
const enhance = compose(
  reduxForm({
    form: "myform",
    initialValues: { firstname: "john" }
  }),
  connect(state => ({
    firstname: valueSelector(state, "firstname")
  }))
);

class Page extends PureComponent {
  render() {
    console.log("firstname", this.props.firstname);
    return (
      <div>
        <Field name="firstname" placeholder="firstname" component="input" />
      </div>
    );
  }
}

export default enhance(Page);
@Olliebaba
Copy link

This appears to be related to #4304.

@jacekkolasa
Copy link
Author

@Olliebaba thx, i also think it's related, but in #4304 there are also lifecycle methods being mentioned, which adds more complexity into this issue. I think it can be related to "Behavior Changes" (second one) mentioned here: https://github.com/reduxjs/react-redux/releases/tag/v6.0.0 and i'm not sure if this can be so easily fixed in redux-form, but maybe a note should be added into Breaking Changes list?

@levino
Copy link

levino commented Jan 15, 2019

Is this being worked on? I think it is a big fat bug, right?

@srisonti
Copy link

Running into the same issue here, any word on this?

@AgentCoop
Copy link

AgentCoop commented Jan 16, 2019

I would suggest to everyone not to migrate to v8 version. With the new context API lots of things got broken. Let them sort things out first.

@jamesmoss
Copy link

As @jacekkolasa mentioned this is indeed due to changes in react-redux 6. When the parent form component mounts it dispatches an action to set the initialValues, however the child components (including the Fields) use the state before the dispatch occured, meaning that they don't see the initialValues. This is intentional in react-redux 6 to prevent what is known as "tearing" where child components get a different version of state than their parents. Most of the time this is great and prevents a whole class of bugs but not in our use case.

There is a great detailed discussion of the problem here reduxjs/react-redux#1126

Interestingly there is a workaround provided in this comment reduxjs/react-redux#1126 (comment) - wrapping the Field component in a new <ReactReduxContext.Provider> should give it access to the most current version of the state.

I don't have time to work on a fix right now but hopefully this points somebody in the right direction.

@vincentjames501
Copy link

Would love to see this one get some attention. This is definitely the biggest issue affecting V8 adoption for us. @erikras , any ideas?

@denich
Copy link

denich commented Jan 28, 2019

Wrote a simple hoc as a workaround for this issue

const withFieldInitialValueFix = Component => {
  const FieldInitialValueFix = props => {
    const {
      input,
      meta: { touched, initial },
    } = props;

    const isValueNotInitialized = initial && !input.value && !touched;

    const fixedInput = isValueNotInitialized
      ? {
          ...input,
          value: initial,
        }
      : input;

    return <Component {...props} input={fixedInput} />;
  };

  FieldInitialValueFix.propTypes = {
    input: PropTypes.shape({
      value: PropTypes.any,
    }).isRequired,
    meta: PropTypes.shape({
      touched: PropTypes.bool.isRequired,
      initial: PropTypes.any,
    }).isRequired,
  };

  return FieldInitialValueFix;
};

Just wrap your field's component to fix for specific cases, or similar logic can be used to override default Field's behavior.
*mb not be suitable for some edge cases, ex. programmatically remove the value at some point.

I think this is definatly should be hadnled as a bug at least because Field's meta.dirty equalstrue on initial render.

@levino
Copy link

levino commented Jan 29, 2019

I am under the impression that maintenance is not happening here. Is this pipelined to be fixed?

@denich Would it not be easier (and much better) to just write a PR which fixes the issue than patching this manually?

@ingro
Copy link

ingro commented Feb 1, 2019

Thanks for the workaround @denich , hope this will be fixed in the library soon!

@KamiGim
Copy link

KamiGim commented Feb 5, 2019

I think I may have the same problem, but with different function in FieldArray component

this.props.fields.getAll() // return null at first as well

Hope you can take a look at this as well

hsz added a commit to onionful/admin that referenced this issue Feb 5, 2019
@pokonski
Copy link

pokonski commented Feb 7, 2019

Another symptom of this problem is now initial call of validate() receives empty object, despite initialValues being passed to the form. So it breaks validations on FieldArrays which previously worked

@jamesmoss
Copy link

We had to roll back to v7 in the end, v8 is a hot mess right now - I'd recommend people don't use it.

@pokonski
Copy link

pokonski commented Mar 22, 2019

Same, react-redux 6 is completely broken but they are apparently working on a solution

@happier2
Copy link

happier2 commented Apr 4, 2019

We are facing same issue when we use react SSR(server side render). As we know, server side render will only render once on the server side, which resulting in empty input html.

@jamesmoss
Copy link

A quick update for those who don't follow ecosystem updates closely: A few weeks ago react-redux published v7.0.0-beta.0 which is a massive reworking of v6; mostly fixing performance issues but also reverting how child components see state changes made by mounting parent components back to the v5 behaviour:

...updates dispatched in React lifecycle methods are immediately reflected in later component updates.

A few people have already tried the new react-redux beta release with redux-form v8 and it fixes this issue. Once it goes gold, should just be a case of updating the dependency for this project and lots of the issues we're seeing with v8 will be fixed. As a heads up, react-redux v7 now uses hooks internally so requires React 16.8.4 or higher

@TomPradat
Copy link

However when validating datas, you still have the validate method called twice with empty data => https://codesandbox.io/s/v6xpm1222y

@AuthorProxy
Copy link

AuthorProxy commented Aug 4, 2019

the same issues with validation after updating react, redux, form and correlated packages to latest versions, first two calls come with empty data

@levino
Copy link

levino commented Aug 5, 2019

The author has abandoned this project and is now working on final form. Issue should be closed as won't fix

@AuthorProxy
Copy link

AuthorProxy commented Aug 5, 2019

A lot of code is broken at new version and lot of code depends on it right now, and cannot switch to previous redux-form version due withRef react changes. Need time to move old code to final form

@eugensunic
Copy link

Any news on this, facing the same issues even with redux-form 8.3.6

@darekkay
Copy link

This might be resolved with 8.3.10. From a first look, I didn't encounter the problem anymore.

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