Skip to content

Commit

Permalink
Starting the router is a side effect and must be wrapped in useEffect…
Browse files Browse the repository at this point in the history
… for React.StrictMode and React.ConcurrentMode (#607)

Co-authored-by: schlesiger <51380403+schlesiger@users.noreply.github.com>
  • Loading branch information
wallzero and schlesiger committed Feb 23, 2020
1 parent 4c8188f commit 834c755
Showing 1 changed file with 26 additions and 20 deletions.
46 changes: 26 additions & 20 deletions src/components/UIRouter.tsx
@@ -1,6 +1,6 @@
/** @packageDocumentation @reactapi @module components */
import * as React from 'react';
import { useRef } from 'react';
import { useEffect, useRef, useState } from 'react';

import { UIRouter as _UIRouter, UIRouterPlugin, servicesPlugin, PluginFactory } from '@uirouter/core';

Expand All @@ -20,7 +20,7 @@ import { ReactStateDeclaration } from '../interface';
* ```
*/
export const UIRouterContext = React.createContext<_UIRouter>(undefined);
/** @deprecated use [[useRouter]] or React.useContext(UIRouterContext) */
/** @deprecated use [[useRouter]] or React.useContext(UIRouterContext) */
export const UIRouterConsumer = UIRouterContext.Consumer;

export interface UIRouterProps {
Expand Down Expand Up @@ -124,25 +124,31 @@ export const InstanceOrPluginsMissingError = `Router instance or plugins missing
*/
export function UIRouter(props: UIRouterProps) {
const uiRouter = useRef<UIRouterReact>();
const [_hasStarted, start] = useState<boolean>(false);

// Router hasn't been initialised yet, this is the first render
if (!uiRouter.current) {
const { config, states, plugins, router } = props;
if (router) {
uiRouter.current = router;
} else if (plugins) {
// We need to create a new instance of the Router and register plugins, config and states
uiRouter.current = new UIRouterReact();
uiRouter.current.plugin(servicesPlugin); // services plugins is necessary for the router to fuction
plugins.forEach(plugin => uiRouter.current.plugin(plugin));
if (config) config(uiRouter.current);
(states || []).forEach(state => uiRouter.current.stateRegistry.register(state));
} else {
throw new Error(InstanceOrPluginsMissingError);
}
useEffect(() => {
// Router hasn't been initialised yet, this is the first render
if (!uiRouter.current) {
const { config, states, plugins, router } = props;
if (router) {
uiRouter.current = router;
} else if (plugins) {
// We need to create a new instance of the Router and register plugins, config and states
uiRouter.current = new UIRouterReact();
uiRouter.current.plugin(servicesPlugin); // services plugins is necessary for the router to fuction
plugins.forEach(plugin => uiRouter.current.plugin(plugin));
if (config) config(uiRouter.current);
(states || []).forEach(state => uiRouter.current.stateRegistry.register(state));
} else {
throw new Error(InstanceOrPluginsMissingError);
}

uiRouter.current.start();
}
uiRouter.current.start();
start(true);
}
});

return <UIRouterContext.Provider value={uiRouter.current}>{props.children}</UIRouterContext.Provider>;
return uiRouter.current ? (
<UIRouterContext.Provider value={uiRouter.current}>{props.children}</UIRouterContext.Provider>
) : null;
}

0 comments on commit 834c755

Please sign in to comment.