found-relay
Version:
Relay integration for found
151 lines (124 loc) • 4.29 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
var _react = _interopRequireDefault(require("react"));
var _reactRelay = require("react-relay");
var _renderElement = _interopRequireDefault(require("./renderElement"));
const _excluded = ["match", "Component", "isComponentResolved", "hasComponent", "element", "routeChildren", "querySubscription", "fetched"];
const {
hasOwnProperty
} = Object.prototype;
class ReadyStateRenderer extends _react.default.Component {
constructor(props) {
super(props);
this.onUpdate = () => {
if (!this.props.fetched) {
// Ignore subscription updates if our data aren't yet fetched. We'll
// rerender anyway once fetching finishes.
return;
}
const {
match,
Component,
isComponentResolved,
hasComponent,
querySubscription
} = this.props;
const element = (0, _renderElement.default)({
match,
Component,
isComponentResolved,
hasComponent,
querySubscription,
resolving: false
});
this.setState({
element: element || null
});
};
const {
element: _element,
querySubscription: _querySubscription
} = props;
this.state = {
isInitialRender: true,
element: _element,
propsElement: _element,
querySubscription: _querySubscription,
selectionReference: _querySubscription.retain(),
onUpdate: this.onUpdate
};
}
componentDidMount() {
this.props.querySubscription.subscribe(this.onUpdate);
}
static getDerivedStateFromProps({
element,
querySubscription
}, state) {
if (state.isInitialRender) {
return {
isInitialRender: false
};
}
let nextState = null;
if (element !== state.propsElement) {
nextState = {
element,
propsElement: element
};
}
if (querySubscription !== state.querySubscription) {
state.selectionReference.dispose();
state.querySubscription.unsubscribe(state.onUpdate);
nextState = nextState || {};
nextState.querySubscription = querySubscription;
nextState.selectionReference = querySubscription.retain();
querySubscription.subscribe(state.onUpdate);
}
return nextState;
}
componentWillUnmount() {
this.state.selectionReference.dispose();
this.props.querySubscription.unsubscribe(this.onUpdate);
}
render() {
const {
element
} = this.state;
if (!element) {
return element;
}
const _this$props = this.props,
{
routeChildren,
querySubscription
} = _this$props,
ownProps = (0, _objectWithoutPropertiesLoose2.default)(_this$props, _excluded);
const {
props: relayProps
} = querySubscription.readyState;
if (relayProps) {
Object.keys(relayProps).forEach(relayPropName => {
// At least on Node v8.x, it's slightly faster to guard the delete here
// with this hasOwnProperty check.
if (hasOwnProperty.call(ownProps, relayPropName)) {
if (process.env.NODE_ENV !== 'production') {
console.error(`Ignoring <ReadyStateRenderer> prop \`${relayPropName}\` that shadows a Relay prop from its query \`${querySubscription.getQueryName()}\`. This is most likely due to its parent cloning it and adding extraneous Relay props.`);
} // @ts-ignore
delete ownProps[relayPropName];
}
});
}
return /*#__PURE__*/_react.default.createElement(_reactRelay.ReactRelayContext.Provider, {
value: querySubscription.relayContext
}, typeof element === 'function' ? /*#__PURE__*/_react.default.cloneElement(element(routeChildren), ownProps) : /*#__PURE__*/_react.default.cloneElement(element, Object.assign({}, /*#__PURE__*/_react.default.isValidElement(routeChildren) ? {
children: routeChildren
} : routeChildren, ownProps)));
}
}
var _default = ReadyStateRenderer;
exports.default = _default;
module.exports = exports.default;
;