react-router 0.0.0-experimental-f92aa2e1 → 0.0.0-experimental-dc8656c8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # `react-router`
2
2
 
3
+ ## 6.11.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix usage of `Component` API within descendant `<Routes>` ([#10434](https://github.com/remix-run/react-router/pull/10434))
8
+ - Fix bug when calling `useNavigate` from `<Routes>` inside a `<RouterProvider>` ([#10432](https://github.com/remix-run/react-router/pull/10432))
9
+ - Fix usage of `<Navigate>` in strict mode when using a data router ([#10435](https://github.com/remix-run/react-router/pull/10435))
10
+ - Updated dependencies:
11
+ - `@remix-run/router@1.6.1`
12
+
13
+ ## 6.11.0
14
+
15
+ ### Patch Changes
16
+
17
+ - Log loader/action errors to the console in dev for easier stack trace evaluation ([#10286](https://github.com/remix-run/react-router/pull/10286))
18
+ - Fix bug preventing rendering of descendant `<Routes>` when `RouterProvider` errors existed ([#10374](https://github.com/remix-run/react-router/pull/10374))
19
+ - Fix inadvertent re-renders when using `Component` instead of `element` on a route definition ([#10287](https://github.com/remix-run/react-router/pull/10287))
20
+ - Fix detection of `useNavigate` in the render cycle by setting the `activeRef` in a layout effect, allowing the `navigate` function to be passed to child components and called in a `useEffect` there. ([#10394](https://github.com/remix-run/react-router/pull/10394))
21
+ - Switched from `useSyncExternalStore` to `useState` for internal `@remix-run/router` router state syncing in `<RouterProvider>`. We found some [subtle bugs](https://codesandbox.io/s/use-sync-external-store-loop-9g7b81) where router state updates got propagated _before_ other normal `useState` updates, which could lead to footguns in `useEffect` calls. ([#10377](https://github.com/remix-run/react-router/pull/10377), [#10409](https://github.com/remix-run/react-router/pull/10409))
22
+ - Allow `useRevalidator()` to resolve a loader-driven error boundary scenario ([#10369](https://github.com/remix-run/react-router/pull/10369))
23
+ - Avoid unnecessary unsubscribe/resubscribes on router state changes ([#10409](https://github.com/remix-run/react-router/pull/10409))
24
+ - When using a `RouterProvider`, `useNavigate`/`useSubmit`/`fetcher.submit` are now stable across location changes, since we can handle relative routing via the `@remix-run/router` instance and get rid of our dependence on `useLocation()`. When using `BrowserRouter`, these hooks remain unstable across location changes because they still rely on `useLocation()`. ([#10336](https://github.com/remix-run/react-router/pull/10336))
25
+ - Updated dependencies:
26
+ - `@remix-run/router@1.6.0`
27
+
3
28
  ## 6.10.0
4
29
 
5
30
  ### Minor Changes
package/LICENSE.md CHANGED
@@ -1,7 +1,8 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) React Training 2015-2019
4
- Copyright (c) Remix Software 2020-2022
3
+ Copyright (c) React Training LLC 2015-2019
4
+ Copyright (c) Remix Software Inc. 2020-2021
5
+ Copyright (c) Shopify Inc. 2022-2023
5
6
 
6
7
  Permission is hereby granted, free of charge, to any person obtaining a copy
7
8
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  The `react-router` package is the heart of [React Router](https://github.com/remix-run/react-router) and provides all
4
4
  the core functionality for both
5
- [`react-router-dom`](/packages/react-router-dom)
5
+ [`react-router-dom`](https://github.com/remix-run/react-router/tree/main/packages/react-router-dom)
6
6
  and
7
- [`react-router-native`](/packages/react-router-native).
7
+ [`react-router-native`](https://github.com/remix-run/react-router/tree/main/packages/react-router-native).
8
8
 
9
9
  If you're using React Router, you should never `import` anything directly from
10
10
  the `react-router` package, but you should have everything you need in either
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * React Router v0.0.0-experimental-f92aa2e1
2
+ * React Router v0.0.0-experimental-dc8656c8
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -61,7 +61,8 @@ if (process.env.NODE_ENV !== "production") {
61
61
 
62
62
  const RouteContext = /*#__PURE__*/React.createContext({
63
63
  outlet: null,
64
- matches: []
64
+ matches: [],
65
+ isDataRoute: false
65
66
  });
66
67
 
67
68
  if (process.env.NODE_ENV !== "production") {
@@ -192,16 +193,19 @@ function useIsomorphicLayoutEffect(cb) {
192
193
 
193
194
 
194
195
  function useNavigate() {
195
- let isDataRouter = React.useContext(DataRouterContext) != null; // Conditional usage is OK here because the usage of a data router is static
196
+ let {
197
+ isDataRoute
198
+ } = React.useContext(RouteContext); // Conditional usage is OK here because the usage of a data router is static
196
199
  // eslint-disable-next-line react-hooks/rules-of-hooks
197
200
 
198
- return isDataRouter ? useNavigateStable() : useNavigateUnstable();
201
+ return isDataRoute ? useNavigateStable() : useNavigateUnstable();
199
202
  }
200
203
 
201
204
  function useNavigateUnstable() {
202
205
  !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
203
206
  // router loaded. We can help them understand how to avoid that.
204
207
  "useNavigate() may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
208
+ let dataRouterContext = React.useContext(DataRouterContext);
205
209
  let {
206
210
  basename,
207
211
  navigator
@@ -233,16 +237,18 @@ function useNavigateUnstable() {
233
237
  }
234
238
 
235
239
  let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === "path"); // If we're operating within a basename, prepend it to the pathname prior
236
- // to handing off to history. If this is a root navigation, then we
237
- // navigate to the raw basename which allows the basename to have full
238
- // control over the presence of a trailing slash on root links
240
+ // to handing off to history (but only if we're not in a data router,
241
+ // otherwise it'll prepend the basename inside of the router).
242
+ // If this is a root navigation, then we navigate to the raw basename
243
+ // which allows the basename to have full control over the presence of a
244
+ // trailing slash on root links
239
245
 
240
- if (basename !== "/") {
246
+ if (dataRouterContext == null && basename !== "/") {
241
247
  path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
242
248
  }
243
249
 
244
250
  (!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);
245
- }, [basename, navigator, routePathnamesJson, locationPathname]);
251
+ }, [basename, navigator, routePathnamesJson, locationPathname, dataRouterContext]);
246
252
  return navigate;
247
253
  }
248
254
 
@@ -574,6 +580,14 @@ function _renderMatches(matches, parentMatches, dataRouterState) {
574
580
 
575
581
  if (error) {
576
582
  children = errorElement;
583
+ } else if (match.route.Component) {
584
+ // Note: This is a de-optimized path since React won't re-use the
585
+ // ReactElement since it's identity changes with each new
586
+ // React.createElement call. We keep this so folks can use
587
+ // `<Route Component={...}>` in `<Routes>` but generally `Component`
588
+ // usage is only advised in `RouterProvider` when we can convert it to
589
+ // `element` ahead of time.
590
+ children = /*#__PURE__*/React.createElement(match.route.Component, null);
577
591
  } else if (match.route.element) {
578
592
  children = match.route.element;
579
593
  } else {
@@ -584,7 +598,8 @@ function _renderMatches(matches, parentMatches, dataRouterState) {
584
598
  match: match,
585
599
  routeContext: {
586
600
  outlet,
587
- matches
601
+ matches,
602
+ isDataRoute: dataRouterState != null
588
603
  },
589
604
  children: children
590
605
  });
@@ -601,7 +616,8 @@ function _renderMatches(matches, parentMatches, dataRouterState) {
601
616
  children: getChildren(),
602
617
  routeContext: {
603
618
  outlet: null,
604
- matches
619
+ matches,
620
+ isDataRoute: true
605
621
  }
606
622
  }) : getChildren();
607
623
  }, null);
@@ -861,16 +877,10 @@ function RouterProvider(_ref) {
861
877
  fallbackElement,
862
878
  router
863
879
  } = _ref;
864
- let [state, setState] = React.useState(router.state); // Need to use a layout effect here so we are subscribed early enough to
880
+ // Need to use a layout effect here so we are subscribed early enough to
865
881
  // pick up on any render-driven redirects/navigations (useEffect/<Navigate>)
866
-
867
- React.useLayoutEffect(() => {
868
- return router.subscribe(newState => {
869
- if (newState !== state) {
870
- setState(newState);
871
- }
872
- });
873
- }, [router, state]);
882
+ let [state, setState] = React.useState(router.state);
883
+ React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
874
884
  let navigator = React.useMemo(() => {
875
885
  return {
876
886
  createHref: router.createHref,
@@ -980,22 +990,22 @@ function Navigate(_ref4) {
980
990
  // the router loaded. We can help them understand how to avoid that.
981
991
  "<Navigate> may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
982
992
  process.env.NODE_ENV !== "production" ? UNSAFE_warning(!React.useContext(NavigationContext).static, "<Navigate> must not be used on the initial render in a <StaticRouter>. " + "This is a no-op, but you should modify your code so the <Navigate> is " + "only ever rendered in response to some user interaction or state change.") : void 0;
983
- let dataRouterState = React.useContext(DataRouterStateContext);
984
- let navigate = useNavigate();
985
- React.useEffect(() => {
986
- // Avoid kicking off multiple navigations if we're in the middle of a
987
- // data-router navigation, since components get re-rendered when we enter
988
- // a submitting/loading state
989
- if (dataRouterState && dataRouterState.navigation.state !== "idle") {
990
- return;
991
- }
993
+ let {
994
+ matches
995
+ } = React.useContext(RouteContext);
996
+ let {
997
+ pathname: locationPathname
998
+ } = useLocation();
999
+ let navigate = useNavigate(); // Resolve the path outside of the effect so that when effects run twice in
1000
+ // StrictMode they navigate to the same place
992
1001
 
993
- navigate(to, {
994
- replace,
995
- state,
996
- relative
997
- });
998
- });
1002
+ let path = resolveTo(to, UNSAFE_getPathContributingMatches(matches).map(match => match.pathnameBase), locationPathname, relative === "path");
1003
+ let jsonPath = JSON.stringify(path);
1004
+ React.useEffect(() => navigate(JSON.parse(jsonPath), {
1005
+ replace,
1006
+ state,
1007
+ relative
1008
+ }), [navigate, jsonPath, relative, replace, state]);
999
1009
  return null;
1000
1010
  }
1001
1011