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

[v7.4.0] initialValues not working #4069

Closed
albermav opened this issue Jun 12, 2018 · 38 comments · Fixed by #4079 · May be fixed by #4599
Closed

[v7.4.0] initialValues not working #4069

albermav opened this issue Jun 12, 2018 · 38 comments · Fixed by #4079 · May be fixed by #4599
Labels

Comments

@albermav
Copy link

Are you submitting a bug report or a feature request?

bug report

What is the current behavior?

initialValues prop is not working on initial mount after update to 7.4.0

Sandbox Link

I've modified the Initialize from state demo just to show the issue. I've just change:

 state => ({
    initialValues: data
 }),

to get values directly from the variable instead after clicking the button.

https://codesandbox.io/s/ox3p66023q

As you can see the fields are empty. If you change the redux-form version to 7.3.0 it works.

What's your environment?

redux-form 7.4.0

@lhtdesignde
Copy link

lhtdesignde commented Jun 13, 2018

just updated from 7.3 to 7.4 and seeing the same thing. all our initial values are gone. seeing no errors. using redux 4.0.0

@cwallervand
Copy link

Same issue here. Using redux v 3.x.x. Had to downgrade to v.7.3to make things work again

@lhtdesignde
Copy link

I updated to react 16.4 and that seemed to have fixed it. I was using 15.4 before.

@schwermer
Copy link

I can confirm this issue on react 15.6.2. The redux-form/INITIALIZE event does not fire

@gustavohenke
Copy link
Collaborator

Thanks for the confirmation, folks.
If you can look at this issue and find a proper fix, we'll be able to get this released sooner.

@vladhd93
Copy link

also i have a lot of bugs with 7.4.0, in general form init and validators not working at all (react 15.6.2 and redux-form 7.4.0). now i'm looking where is problem

@JoshMock
Copy link

JoshMock commented Jun 13, 2018

I just spent a couple hours trying to diagnose this as well. Pinning to version 7.3.0 in your package.json will fix the issue.

It appears that, in createReduxForm, componentWillMount is no longer being called, and thus initIfNeeded is not hitting its first pass at initialization because a nextProps argument is always passed by componentDidMount (the next lifecycle method that calls initIfNeeded).

This is because the method name changed to UNSAFE_componentWillMount in order to support React 16's unsafe versions of deprecated lifecycle methods. By doing so, support for React v15 is now broken in v7.4.0.

I would imagine that having two methods, UNSAFE_componentWillMount and componentWillMount, living side by side doing the same work, would guarantee full support for React 15 and 16, but I haven't tried yet. EDIT: Or you could just go back to only using componentWillMount, as that is still going to be supported until React 17 comes out, at which point this package could do a major version breaking change bump to support React 17.

Maintainers, please let me know if you'd like a PR with my proposed solution!

@andrewnaeve
Copy link

I'm just glad to see the Redux Forms authors have as tough a time testing their library as I do.

@paynecodes
Copy link

paynecodes commented Jun 14, 2018

Adding to @JoshMock's point, it appears that react-final-form has a dependency on react-lifecycles-compat for this reason. Perhaps this is the simple fix? I'm not sure, but will try to test later this afternoon if someone doesn't get to it before I do.

@gustavohenke
Copy link
Collaborator

gustavohenke commented Jun 14, 2018

Hello folks, thanks for looking at this issue with a magnifying glass.
We don't really have workforce to deal with code changes nowadays (most recent changes are from you, dear users), so if any of you could make the PR, that would be great.
I think @jpdesigndev's idea is simple enough to require little review, so I would 👍 it 🙂

@danielrob
Copy link
Collaborator

danielrob commented Jun 15, 2018

@gustavohenke, @jpdesigndev, @JoshMock
Let's be clear:

  • The hotfix should be to revert to the straight cWM, cWRP, and cWU. See Hotfix: Revert all UNSAFE_ lifecycle methods #4078.
  • The actual fix is to migrate all uses of these old life cycle methods, when doing so we use react-lifecycles-compat to continue support for React 15. Until then we cannot avoid the deprecation warnings that come with StrictMode in React 16.4.
  • Use of UNSAFE_ methods are only appropriate when the React version is known to be 16+ (i.e. for application authors).

See: open-source-project-maintainers & gradual-migration-path sections of the react blogs update-on-async-rendering

@erikras
Copy link
Member

erikras commented Jun 15, 2018

Published fix in v7.4.1.

Not fixed yet.

@albermav
Copy link
Author

Thank you guys for the follow up!. You are awesome. I'm afraid i've got some bad news. Just update to v4.7.1 but it's still not working. I've updated the redux-form version in codesandbox and the problem persist.

@erikras
Copy link
Member

erikras commented Jun 15, 2018

Published ACTUAL fix in v7.4.2.

@albermav
Copy link
Author

It is working now. BIG thanks!

@jedwards1211
Copy link
Contributor

jedwards1211 commented Aug 28, 2018

Thank you guys!
I thought I was having this issue but after I upgraded I realized that I'm seeing #3879 (reduxForm just passes through the initialValues prop, which I'm not using; calling initialize() doesn't affect the initialValues it passes to the wrapped component 😱 ). I was really confused by this... it doesn't seem wise to pass initialValues to the wrapped component unless it is the initial coming from redux state.

@ViggoV
Copy link

ViggoV commented Sep 18, 2018

@jedwards1211 could you elaborate? I seem to have the same issue with version 7.4.2 and React 16.5.0, but there is a very real possibility I might have overlooked something..

@jedwards1211
Copy link
Contributor

jedwards1211 commented Sep 18, 2018

Actually, I finally found an issue someone already filed for what I'm talking about: #3459
(initialize() action creator should update initialValues props)

@dwjohnston
Copy link

I believe this is still a bug, my solution is to call this.props.initialize() in componentDidMount();

@dwjohnston
Copy link

^^ Here's a sandbox: https://codesandbox.io/s/ryo81qz60q

@ThaiVanLoiDN
Copy link

ThaiVanLoiDN commented Mar 3, 2019

[redux-form version 8.1.0]
I use this.props.initialize() in componentDidMount(), it's OK.
However, if I use it in componentWillReceiveProps, it not working.

@nileshkikani
Copy link

I have tried above solution but still its not working. It's not updating initial value of props.

redux state and everything is fine but rerender is not being called.

@karpovich-philip
Copy link

karpovich-philip commented Apr 5, 2019

I believe this is still a bug, my solution is to call this.props.initialize() in componentDidMount();

One more option:
componentDidMount { this.props.initialize(this.props.myFormData) }

@blopa
Copy link

blopa commented Jul 10, 2019

I'm having the same problem with "redux-form": "^8.2.3", and "react": "^16.8.6",.

Calling this.props.initialize() in componentDidMount(); worked for me!

@m1m6
Copy link

m1m6 commented Jul 15, 2019

I'm having the same problem with "redux-form": "^8.2.3", and "react": "^16.8.6",.

Calling this.props.initialize() in componentDidMount(); worked for me!

Same here

@goodwin64
Copy link
Contributor

Bug still can be reproduced under "redux-form": "8.2.2" and "react": "^16.8.6". The issue has to be reopened.

@abemedia
Copy link

I can confirm this is still an issue ([email protected] & [email protected]).

@made-in-nz
Copy link

I have a slightly different work around.
I want to keep my component functional, so don't want to call initialize() in a lifecycle method. The work around I have for setting initial values from state is to call change() in a useEffect hook. In my case I am wanting to set a form value to some state that is not changing:

  /* Workaround to be able to call change in useEffect
     regtype here is a prop mapped to some state in mapStateToProps.
   */      
  const latestChange = useRef(change);
  useEffect(() => {
    latestChange.current = change;
  }, [change]);

  useEffect(() => {
    latestChange.current('RecordType', regtype);
  }, [regtype]);

The first useEffect() is required so that we don't need to add change as a dependency in the second (which would cause the useEffect function to execute continuosly).

I'm sure there are better ways to do this..

@jedwards1211
Copy link
Contributor

@made-in-nz FWIW you don't need that first useEffect, you can just do this

const latestChange = useRef(change);
latestChange.current = change;

And really, you can probably just get away with

  useEffect(() => {
    change('RecordType', regtype);
  }, [regtype]);

because the closure of that function always comes from a single render, so change and regtype will be equally up-to-date.

@made-in-nz
Copy link

Thanks @jedwards1211 for the first suggestion, that makes sense.
The second suggestion is what I started with, however I am then getting the warnings:

React Hook useEffect has a missing dependency: 'change'. Either include it or remove the dependency array. If 'change' changes too often, find the parent component that defines it and wrap that definition in useCallback react-hooks/exhaustive-deps

The behaviour is fine though.

@jedwards1211
Copy link
Contributor

jedwards1211 commented Dec 12, 2019

Yeah, that's a linting rule designed to make sure you don't accidentally leave out necessary dependencies...it can be nice to intentionally omit something in cases like this, but having the linting rule is also handy 🤷‍♂
I guess the linting rule only excludes refs from consideration?

@andrew-aladev
Copy link

This issue can be easily reproduced by providing same initialValues twice.

@treavis
Copy link

treavis commented Jan 14, 2020

This issue can be easily reproduced by providing same initialValues twice.

Can confirm, for me this was the reason the form values did not update. Thank you @andrew-aladev for pointing this out 🙏

@andrew-aladev
Copy link

Something is completely wrong with the following lines of code.

It is hard to understand this logic. I am reproducing issue with the following env:

const stateInitial ... // undefined
const initialized ... // false
const shouldUpdateInitialValues ... // false
const shouldResetValues ... // false
let initial ... // { ... good data }
initial = stateInitial || empty // { empty object }

So it looks like logic is broken here:

if (!shouldUpdateInitialValues) {
  initial = stateInitial || empty
}

We don't need to update initial values, but why we are resetting it with empty object? See here the following blame.

Everything except if (!shouldUpdateInitialValues) { was updated 3 years ago, but this code is only 1 year ago. So there was some legacy code and people failed to fix it.

@andrew-aladev
Copy link

This small commit was related to #4020 and it is wrong. We need to fix this issue in another way.

@andrew-aladev
Copy link

I've updated this code with the following:

const stateInitial = getIn(formState, 'initial')
const stateValues = getIn(formState, 'values')

const initialized = !!stateInitial
const valuesInitialized = !!stateValues

const shouldReinitialize =
  initialized && enableReinitialize &&
  !deepEqual(stateInitial, initialValues)
const shouldUpdateInitial =
  !initialized || shouldReinitialize
const shouldUpdateValues =
  (!valuesInitialized || shouldUpdateInitial) &&
  !keepDirtyOnReinitialize

const initial = shouldUpdateInitial ? initialValues : stateInitial
const values = shouldUpdateValues ? initial : stateValues

const pristine = shouldUpdateValues || deepEqual(initial, values)

Now both initial and values are right, but issue is not fixed, there is bug in another code too.

@andrew-aladev
Copy link

andrew-aladev commented Jan 16, 2020

The following code initIfNeeded is broken too.

When shouldUpdateInitial is true, initIfNeeded don't want to make initialization.

if ((enableReinitialize || !nextProps.initialized) && !deepEqual(this.props.initialValues, nextProps.initialValues)) {

This code is broken.

@andrew-aladev
Copy link

andrew-aladev commented Jan 16, 2020

The line above should be the following:

if (nextProps.initialValues && (!nextProps.initialized || (nextProps.enableReinitialize && !deepEqual(this.props.initialValues, nextProps.initialValues)))) {

I've tested it in our current project and it works perfect.

I will create a pull request later.

andrew-aladev added a commit to andrew-aladev/redux-form that referenced this issue Jan 17, 2020
andrew-aladev added a commit to andrew-aladev/redux-form that referenced this issue Jan 17, 2020
andrew-aladev added a commit to andrew-aladev/redux-form that referenced this issue Jan 17, 2020
andrew-aladev added a commit to andrew-aladev/redux-form that referenced this issue Jan 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet