react-render-props-script-loader
Version:
an easier to use dynamic script loader
65 lines • 2.13 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import * as React from 'react';
import loadScript, { getState } from "./loadScript.mjs";
export function useScript(props) {
const isMounted = React.useRef(true);
React.useEffect(() => () => {
isMounted.current = false;
}, []);
const scriptsRegistry = React.useContext(ScriptsRegistryContext);
const [, rerender] = React.useReducer((count = 0) => count + 1);
const propsRef = React.useRef(props);
propsRef.current = props;
const act = React.useCallback(fn => {
if (!isMounted.current) return;
const {
act
} = propsRef.current;
if (act) act(fn);else fn();
}, []);
const promise = React.useMemo(() => loadScript({
...props,
scriptsRegistry
}), [props.src, scriptsRegistry]);
React.useEffect(() => {
if (!isMounted.current) return;
promise.then(() => act(() => {
var _propsRef$current$onL, _propsRef$current;
(_propsRef$current$onL = (_propsRef$current = propsRef.current).onLoad) === null || _propsRef$current$onL === void 0 ? void 0 : _propsRef$current$onL.call(_propsRef$current);
rerender();
}), error => act(() => {
var _propsRef$current$onE, _propsRef$current2;
(_propsRef$current$onE = (_propsRef$current2 = propsRef.current).onError) === null || _propsRef$current$onE === void 0 ? void 0 : _propsRef$current$onE.call(_propsRef$current2, error);
rerender();
}));
}, [promise]);
return getState({
...props,
scriptsRegistry
});
}
export class ScriptsRegistry {
scripts = [];
results = {};
promises = {};
scriptTags(options) {
return this.scripts.map(props => /*#__PURE__*/React.createElement("script", _extends({}, props, {
key: props.src,
nonce: options ? options.nonce : undefined
})));
}
}
export const ScriptsRegistryContext = /*#__PURE__*/React.createContext(null);
export default function ScriptLoader(props) {
const state = useScript(props);
const {
children
} = props;
if (children) {
const result = children({
...state
});
return result == null ? null : result;
}
return null;
}