Skip to content

Commit

Permalink
fix(DeviceSize): refactor fallback detection to only apply before med…
Browse files Browse the repository at this point in the history
…ia listeners are initialized

test(DeviceSize): add missing test for derived state from fallbackDetection prop
  • Loading branch information
shYkiSto authored and ooHmartY committed Jul 19, 2018
1 parent 7725a4f commit 8c256d3
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
30 changes: 22 additions & 8 deletions src/components/DeviceSize/Provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand All @@ -74,12 +94,6 @@ export default class DeviceSizeProvider extends React.Component {
};

render() {
const { fallbackDetection } = this.props;
const val = fallbackDetection ? fallbackDetection() : this.state;
return (
<Provider value={val || this.initialState}>
{this.props.children}
</Provider>
);
return <Provider value={this.state}>{this.props.children}</Provider>;
}
}
21 changes: 21 additions & 0 deletions src/components/DeviceSize/__test__/Provider.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
});

0 comments on commit 8c256d3

Please sign in to comment.