diff --git a/src/components/DeviceSize/Provider.js b/src/components/DeviceSize/Provider.js
index b4fc958c9..cf176cfe1 100644
--- a/src/components/DeviceSize/Provider.js
+++ b/src/components/DeviceSize/Provider.js
@@ -8,13 +8,32 @@ import constants from "../../theme/constants";
export default class DeviceSizeProvider extends React.Component {
static propTypes = {
children: PropTypes.node.isRequired,
+ // https://github.com/yannickcr/eslint-plugin-react/issues/1751
+ // eslint-disable-next-line
fallbackDetection: PropTypes.func,
cssOnly: PropTypes.bool
};
static defaultProps = { fallbackDetection: null, cssOnly: false };
- initialState = { isSmall: true }; // eslint-disable-line
+ initialState = { isInitialized: false, isSmall: true }; // eslint-disable-line
+
+ static getDerivedStateFromProps(props, state) {
+ if (!state.isInitialized && typeof props.fallbackDetection === "function") {
+ const fallbackDetectionResult = props.fallbackDetection();
+
+ if (
+ typeof fallbackDetectionResult === "object" &&
+ fallbackDetectionResult !== null
+ ) {
+ return {
+ ...fallbackDetectionResult
+ };
+ }
+ }
+
+ return null;
+ }
state = this.initialState;
@@ -58,6 +77,7 @@ export default class DeviceSizeProvider extends React.Component {
}
this.setState(() => ({
+ isInitialized: true,
isSmall: this.smallMedia.matches && !this.mediumMedia.matches,
isMedium: this.mediumMedia.matches && !this.largeMedia.matches,
isLarge: this.largeMedia.matches && !this.xLargeMedia.matches,
@@ -74,12 +94,6 @@ export default class DeviceSizeProvider extends React.Component {
};
render() {
- const { fallbackDetection } = this.props;
- const val = fallbackDetection ? fallbackDetection() : this.state;
- return (
-
- {this.props.children}
-
- );
+ return {this.props.children};
}
}
diff --git a/src/components/DeviceSize/__test__/Provider.spec.js b/src/components/DeviceSize/__test__/Provider.spec.js
index 676499994..7bacb4342 100644
--- a/src/components/DeviceSize/__test__/Provider.spec.js
+++ b/src/components/DeviceSize/__test__/Provider.spec.js
@@ -76,4 +76,25 @@ describe("DeviceSize", () => {
expect(removeListener).toHaveBeenCalled();
});
});
+
+ describe("getDerivedStateFromProps()", () => {
+ it("should use fallbackDetection data to populate derived state", () => {
+ const fallbackDevices = { isSmall: false, isLarge: true };
+ const fallbackDetection = jest
+ .fn()
+ .mockImplementation(() => fallbackDevices);
+
+ const derivedState = Provider.getDerivedStateFromProps(
+ {
+ fallbackDetection
+ },
+ {
+ isInitialized: false
+ }
+ );
+
+ expect(fallbackDetection).toHaveBeenCalled();
+ expect(derivedState).toEqual(fallbackDevices);
+ });
+ });
});