简体   繁体   中英

React-Query / React Router V5 insert state variable from api response into route but only when response has finished

In my app, I have an api call which gets some data (Array of objects), I then use this in a context and share this across my app. What I want to do is use some of that data ie object value and prefix it to my routes. The API handling is done via react-query.

I have tried just accessing the variable and inserting it as follows:

const Routing: React.FunctionComponent = () => {
  const { valueFromContext } = React.useContext(DataContext);

  const basePrefix = valueFromContext?.name;

  return (
    <>
        <BrowserRouter >
          <Header />
          <div className="App">
            <Switch>
              <Route exact path={["/", "/dashboard"]}>
                <Redirect to={`/${basePrefix}/home`} />
              </Route>
              <Route exact path={[`/${basePrefix}/home`, "/"]} component={Home} />
              <Route exact path={`/account/:id`} render={(props: RouteComponentProps<any>) => <Account {...props} />} />
              <Route component={NotFound} />
            </Switch>
          </div>
        </BrowserRouter>
    </>
  )
}

So problem is this is inconsistent, as sometimes the url comes back as '/undefined/home' and shows the 404 not found component, so I am thinking the route is being inserted before the response has finished?

Any idea's?

Yes, it appears that on the initial render cycle that basePrefix , or valueFromContext?.name , yields an undefined value. You can apply some conditional rendering logic to return null or a loading indicator while the basePrefix value is fetched/computed.

Example:

const Routing: React.FunctionComponent = () => {
  const { valueFromContext } = React.useContext(DataContext);

  const basePrefix = valueFromContext?.name;

  return basePrefix
    ? (
      <BrowserRouter >
        <Header />
        <div className="App">
          <Switch>
            <Route exact path={["/", "/dashboard"]}>
              <Redirect to={`/${basePrefix}/home`} />
            </Route>
            <Route exact path={[`/${basePrefix}/home`, "/"]} component={Home} />
            <Route exact path={`/account/:id`} render={(props: RouteComponentProps<any>) => <Account {...props} />} />
            <Route component={NotFound} />
          </Switch>
        </div>
      </BrowserRouter>
    )
    : null; // <-- or loading indicator/spinner/etc
}

In your closely related question here notice that I provided a valid defined baseprefix value from the context for this reason, to not accidentally inject undefined into the URL path.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM