cl-react-graph
Version:
149 lines (115 loc) • 4.62 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _loader = _interopRequireDefault(require("./loader"));
var _shallowCompare = _interopRequireDefault(require("shallow-compare"));
let isInitialRender = true; // Pass pathname in as prop.
// component will try fetching resources. If they exist,
// will just render, else will render null.
// It will also wait for pageResources
// before propagating location change to children.
class EnsureResources extends _react.default.Component {
constructor(props) {
super();
let location = props.location;
this.state = {
location: Object.assign({}, location),
pageResources: _loader.default.getResourcesForPathnameSync(location.pathname)
};
}
reloadPage(prevHref) {
// Do this, rather than simply `window.location.reload()`, so that
// pressing the back/forward buttons work - otherwise when pressing
// back, the browser will just change the URL and expect JS to handle
// the change, which won't always work since it might not be a Gatsby
// page.
const href = window.location.href;
window.history.replaceState({}, ``, prevHref);
window.location.replace(href);
}
static getDerivedStateFromProps({
location
}, prevState) {
if (prevState.location !== location) {
const pageResources = _loader.default.getResourcesForPathnameSync(location.pathname);
return {
pageResources,
location: Object.assign({}, location)
};
}
return null;
}
hasResources(pageResources) {
if (pageResources && pageResources.json) {
return true;
}
if (pageResources && process.env.NODE_ENV !== `production`) {
return true;
}
return false;
}
retryResources(nextProps) {
const pathname = nextProps.location.pathname;
if (!_loader.default.getResourcesForPathnameSync(pathname)) {
// Store the previous and next location before resolving resources
const prevLocation = this.props.location;
this.nextLocation = nextProps.location; // Page resources won't be set in cases where the browser back button
// or forward button is pushed as we can't wait as normal for resources
// to load before changing the page.
_loader.default.getResourcesForPathname(pathname).then(pageResources => {
// The page may have changed since we started this, in which case doesn't update
if (this.nextLocation !== nextProps.location) {
return;
}
if (this.hasResources(pageResources)) {
this.setState({
location: Object.assign({}, window.location),
pageResources
});
return;
} // If we still don't have resources, reload the page.
// (This won't happen on initial render, since shouldComponentUpdate
// is only called when the component updates.)
this.reloadPage(prevLocation.href);
});
}
}
shouldComponentUpdate(nextProps, nextState) {
// Always return false if we're missing resources.
if (!this.hasResources(nextState.pageResources)) {
this.retryResources(nextProps);
return false;
} // Check if the component or json have changed.
if (this.state.pageResources !== nextState.pageResources) {
return true;
}
if (this.state.pageResources.component !== nextState.pageResources.component) {
return true;
}
if (this.state.pageResources.json !== nextState.pageResources.json) {
return true;
} // Check if location has changed on a page using internal routing
// via matchPath configuration.
if (this.state.location.key !== nextState.location.key && nextState.pageResources.page && (nextState.pageResources.page.matchPath || nextState.pageResources.page.path)) {
return true;
}
return (0, _shallowCompare.default)(this, nextProps, nextState);
}
render() {
if (!this.hasResources(this.state.pageResources) && isInitialRender) {
window.___failedResources = true; // prevent hydrating
throw new Error(`Missing resources for ${this.state.location.pathname}`);
}
isInitialRender = false;
return this.props.children(this.state);
}
}
EnsureResources.propTypes = {
location: _propTypes.default.object.isRequired,
pageResources: _propTypes.default.object
};
var _default = EnsureResources;
exports.default = _default;