Skip to content

Commit

Permalink
[V2] Upgrade to react 16 (rjsf-team#1408)
Browse files Browse the repository at this point in the history
* upgrade to react 16

* bump react peer dependency to 16

* remove react-lifecycles polyfill

* unskip react 16 test

* Fix array tests, fixes rjsf-team#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
  • Loading branch information
epicfaace committed Sep 9, 2019
1 parent e78ab11 commit 18b2ec4
Show file tree
Hide file tree
Showing 15 changed files with 141 additions and 105 deletions.
104 changes: 72 additions & 32 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,15 @@
"node": ">=6"
},
"peerDependencies": {
"react": ">=15"
"react": ">=16"
},
"dependencies": {
"@babel/runtime-corejs2": "^7.4.5",
"ajv": "^6.7.0",
"core-js": "^2.5.7",
"lodash": "^4.17.15",
"prop-types": "^15.5.8",
"react-is": "^16.8.4",
"react-lifecycles-compat": "^3.0.4",
"react-is": "^16.9.0",
"shortid": "^2.2.14"
},
"devDependencies": {
Expand Down Expand Up @@ -91,9 +90,9 @@
"monaco-editor-webpack-plugin": "^1.7.0",
"nyc": "^13.2.0",
"prettier": "^1.15.1",
"react": "^15.5.0",
"react": "^16.9.0",
"react-codemirror2": "^4.1.0",
"react-dom": "^15.3.2",
"react-dom": "^16.9.0",
"react-monaco-editor": "^0.26.2",
"react-portal": "^4.2.0",
"react-transform-catch-errors": "^1.0.0",
Expand Down
2 changes: 1 addition & 1 deletion playground/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class Editor extends Component {
this.state = { valid: true, code: props.code };
}

componentWillReceiveProps(props) {
UNSAFE_componentWillReceiveProps(props) {
this.setState({ valid: true, code: props.code });
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default class Form extends Component {
this.formElement = null;
}

componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) {
const nextState = this.getStateFromProps(nextProps, nextProps.formData);
if (
!deepEquals(nextState.formData, nextProps.formData) &&
Expand Down
14 changes: 10 additions & 4 deletions src/components/fields/ArrayField.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import AddButton from "../AddButton";
import IconButton from "../IconButton";
import React, { Component } from "react";
import { polyfill } from "react-lifecycles-compat";
import includes from "core-js/library/fn/array/includes";
import * as types from "../../types";

Expand Down Expand Up @@ -212,10 +211,17 @@ class ArrayField extends Component {
const keyedFormData = generateKeyedFormData(formData);
this.state = {
keyedFormData,
updatedKeyedFormData: false,
};
}

static getDerivedStateFromProps(nextProps, prevState) {
// Don't call getDerivedStateFromProps if keyed formdata was just updated.
if (prevState.updatedKeyedFormData) {
return {
updatedKeyedFormData: false,
};
}
const nextFormData = nextProps.formData;
const previousKeyedFormData = prevState.keyedFormData;
const newKeyedFormData =
Expand Down Expand Up @@ -281,10 +287,10 @@ class ArrayField extends Component {
item: this._getNewFormDataRow(),
};
const newKeyedFormData = [...this.state.keyedFormData, newKeyedFormDataRow];

this.setState(
{
keyedFormData: newKeyedFormData,
updatedKeyedFormData: true,
},
() => onChange(keyedToPlainFormData(newKeyedFormData))
);
Expand All @@ -306,6 +312,7 @@ class ArrayField extends Component {
this.setState(
{
keyedFormData: newKeyedFormData,
updatedKeyedFormData: true,
},
() => onChange(keyedToPlainFormData(newKeyedFormData))
);
Expand Down Expand Up @@ -337,6 +344,7 @@ class ArrayField extends Component {
this.setState(
{
keyedFormData: newKeyedFormData,
updatedKeyedFormData: true,
},
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
);
Expand Down Expand Up @@ -778,6 +786,4 @@ if (process.env.NODE_ENV !== "production") {
ArrayField.propTypes = types.fieldProps;
}

polyfill(ArrayField);

export default ArrayField;
2 changes: 1 addition & 1 deletion src/components/fields/MultiSchemaField.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class AnyOfField extends Component {
};
}

componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) {
const matchingOption = this.getMatchingOption(
nextProps.formData,
nextProps.options
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/AltDateWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class AltDateWidget extends Component {
this.state = parseDateString(props.value, props.time);
}

componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) {
this.setState(parseDateString(nextProps.value, nextProps.time));
}

Expand Down
5 changes: 4 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@ export function getWidget(schema, widget, registeredWidgets = {}) {
return Widget.MergedWidget;
}

if (typeof widget === "function" || ReactIs.isForwardRef(widget)) {
if (
typeof widget === "function" ||
ReactIs.isForwardRef(React.createElement(widget))
) {
return mergeOptions(widget);
}

Expand Down
Loading

0 comments on commit 18b2ec4

Please sign in to comment.