Home > Mobile >  Uncaught Error: [Elements] is not a <Route> component. All component children of <Routes>
Uncaught Error: [Elements] is not a <Route> component. All component children of <Routes>

Time:07-16

I was trying to integrate the strip API key but I am not able to come up with the solution in the new react-router-dom version

here is the full error

The above error occurred in the component:

at Routes (http://localhost:3000/static/js/bundle.js:81119:5)
at Router (http://localhost:3000/static/js/bundle.js:81052:15)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:79861:5)
at App (http://localhost:3000/main.79cc3231add2da1b35a8.hot-update.js:89:63)
at Provider (http://localhost:3000/static/js/bundle.js:74963:5)

Consider adding an error boundary to your tree to customize error handling behavior. Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

here is my Appjs Protected route code:

import { Elements } from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";

useEffect(() => {
store.dispatch(loadUser());
getStripeApiKey();
}, []);

useEffect(() => {
 const stripePromise= loadStripe(stripeApiKey);
}, [stripeApiKey]);



<Route element={<ProtectedRoute />}>
      <Route path="/account" element={<Profile />} />
      <Route path="/me/update" element={<ProfileEdit />} />
      <Route path="/password/update" element={<UpdatePassword />} />
      <Route path="/login/shipping" element={<Shipping />} />
      <Route path="/order/confirm" element={<ConfirmOrder />} />
      {stripeApiKey && (
        <Elements stripe={stripePromise}>
          <Route path="/order/payment" element={<Payment />} />
        </Elements>
      )}
</Route>

My protected route code

const ProtectedRoute = () => {
const { loading, isAuthenticated, user } = useSelector((state) => state.user);
const location = useLocation();

if (isAuthenticated == false) {
return <Navigate to="/account" state={{ from: location }} />;
}
return <Outlet />;
};

export default ProtectedRoute;

CodePudding user response:

You are getting that error because of this line of code

 {stripeApiKey && (
        <Elements stripe={stripePromise}>
          <Route path="/order/payment" element={<Payment />} />
        </Elements>
      )}

Only Route or React.Fragment are allowed to be children of the Routes component. But in your case if stripeApiKey turns out to be true , you are rendering Elements component which contradicts the new react router v6 rules

Like you asked in comments you want to wrap your payments method

<Route path="/order/payment" element={<Elements stripe={stripePromise}><Payment /></Elements} />

CodePudding user response:

Issue

This issue is that you are rendering something other than a Route or React.Fragment inside the Routes component.

{stripeApiKey && (
  <Elements stripe={stripePromise}>
    <Route path="/order/payment" element={<Payment />} />
  </Elements>
)}

The Elements component is neither and fails the invariant check.

Solution

Refactor this into a layout route component similar to the ProtectedRoute component.

Example:

import { Outlet, Navigate } from 'react-router-dom';

const StripeLayout = ({ stripeApiKey }) => {
  return stripeApiKey
    ? <Outlet />
    : <Navigate to="/" replace />
};

...

<Route element={<ProtectedRoute />}>
  <Route path="/account" element={<Profile />} />
  <Route path="/me/update" element={<ProfileEdit />} />
  <Route path="/password/update" element={<UpdatePassword />} />
  <Route path="/login/shipping" element={<Shipping />} />
  <Route path="/order/confirm" element={<ConfirmOrder />} />
  <Route element={<StripeLayout {...{ stripeApiKey }} />}>
    <Route
      path="/order/payment"
      element={(
        <Elements stripe={stripePromise}>
          <Payment />
        </Elements>
      )}
    />
  </Route>
</Route>
  • Related