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

[V2] Upgrade to react 16 #1408

Merged
merged 8 commits into from
Sep 9, 2019
Merged

[V2] Upgrade to react 16 #1408

merged 8 commits into from
Sep 9, 2019

Conversation

epicfaace
Copy link
Member

@epicfaace epicfaace commented Aug 14, 2019

Reasons for making this change

Upgrade to react 16, fixes #1275, fixes #1427 .

If this is related to existing tickets, include links to them as well.

Checklist

  • I'm updating documentation
  • I'm adding or updating code
    • I've added and/or updated tests
    • I've updated docs if needed
  • I'm adding a new feature
    • I've updated the playground with an example use of the feature

@epicfaace
Copy link
Member Author

@fsteger do you know why these tests may be failing on upgrade to React 16:

  1. ArrayField
    List of inputs
    should retain existing row keys/ids when adding new row:

  2. ArrayField
    List of inputs
    should allow inserting anywhere in list:

  3. ArrayField
    List of inputs
    should retain row keys/ids of remaining rows when a row is removed:

@zepatrik
Copy link
Contributor

I had a look into this and it probably depends on some deprecated lifecycle methods used. I can rewrite everything to functional components using hooks as I already have some experience doing that on a large scale. Will be done by today and open a PR then.

@zepatrik
Copy link
Contributor

It is actually more work than expected. I'm still working on that, biggest problem is that keys were used wrong. Seems like react 15 is passing the key prop to the child although it is only for internal use. With react 16 that prop is not accessible.

E.g. this is not accessible here

But getting there.

@epicfaace
Copy link
Member Author

@zepatrik thanks for the update. What exactly is the change between react 15 and react 16 regarding keys? Is it that you can't pass on a key prop to a child? (that sounds strange, because if the key prop is accessible, then you can pass it on, right...?)

@zepatrik
Copy link
Contributor

I could not really find a breaking change in reacts release notes but as you can see here (also look into the console) it is not possible to access the key prop (and apparently it was before)

@zepatrik
Copy link
Contributor

Also static getDerivedStateFromProps() lifecycle is used which was added in react 16.3.0. The tests worked until now because the derived state was not used.

@epicfaace
Copy link
Member Author

What do you mean by "the derived state was not used"? We did use static getDerivedStateFromProps but in combination with a polyfill from "react-lifecycles-compat". Will probably need to remove the polyfill though for react 16.

@zepatrik
Copy link
Contributor

well because it appeared to not have been called, the state differed on the react version

@zepatrik
Copy link
Contributor

Here are some debug information. Logging the nextProps and prevState args of getDerivedStateFromProps in ArrayField

This is also what the first failing test detects.

react 15:
Screenshot from 2019-08-22 12-25-02

react 16:
Screenshot from 2019-08-22 12-23-06

Steps to reproduce:

  1. add a console.log statement
  2. open the array example on the playground
  3. click the add button twice

As you can see for some reason the component updates twice, once with an updated state and once with updated props.

@zepatrik
Copy link
Contributor

tracked that as issue #1427

componentWillReceiveProps is not called after setState, but
getDerivedStateFromProps is called after setState. This caused the array
key tests to fail, because when onAddIndexClick is called, it sets the
state first to update keyedFormData. Only afterwards is the onChange
handler called with the new form data. And, getDerivedStateFromProps is
called in between, so it ends up being called with the old form data
instead of the new one.

Used the technique in https://stackoverflow.com/a/57208053 to work
around this, by not calculating derived state in
getDerivedStateFromProps when keyed form data is
updated.
@edi9999
Copy link
Collaborator

edi9999 commented Sep 9, 2019

Very cool !

@epicfaace epicfaace merged commit f3bd25f into v2 Sep 9, 2019
@epicfaace epicfaace deleted the v2-react-upgrade branch September 9, 2019 13:49
epicfaace added a commit that referenced this pull request Sep 9, 2019
* upgrade to react 16

* bump react peer dependency to 16

* remove react-lifecycles polyfill

* unskip react 16 test

* Fix array tests, fixes #1427

componentWillReceiveProps is not called after setState, but
getDerivedStateFromProps is called after setState. This caused the array
key tests to fail, because when onAddIndexClick is called, it sets the
state first to update keyedFormData. Only afterwards is the onChange
handler called with the new form data. And, getDerivedStateFromProps is
called in between, so it ends up being called with the old form data
instead of the new one.

Used the technique in https://stackoverflow.com/a/57208053 to work
around this, by not calculating derived state in
getDerivedStateFromProps when keyed form data is
updated.

* Remove console.error stub to fix tests

* Fix getWidget behavior for forwarded refs

* Replace componentWillReceiveProps with UNSAFE_componentWillReceiveProps
@epicfaace epicfaace mentioned this pull request Sep 11, 2019
7 tasks
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

Successfully merging this pull request may close these issues.

3 participants