Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V6 Controlled Router #7444

Closed
joacub opened this issue Jun 23, 2020 · 4 comments
Closed

V6 Controlled Router #7444

joacub opened this issue Jun 23, 2020 · 4 comments

Comments

@joacub
Copy link

joacub commented Jun 23, 2020

How do in v6 beta the Controlled router integration ?

@timdorr
Copy link
Member

timdorr commented Jun 23, 2020

Do you mean a Redux-connected router? That's in-progress in another repo: supasate/connected-react-router#397

@timdorr timdorr closed this as completed Jun 23, 2020
@joacub
Copy link
Author

joacub commented Jun 23, 2020

@timdorr
what I mean is this example

const loadBranchData = location => {
  const branch = matchRoutes(routes, location.pathname);

  const promises = branch.map(({ route, match }) => {
    return route.loadData ? route.loadData(match) : Promise.resolve(null);
  });

  return Promise.all(promises);
};

// useful on the server for preloading data
loadBranchData(req.url).then(data => {
  putTheDataSomewhereTheClientCanFindIt(data);
});

// also useful on the client for "pending navigation" where you
// load up all the data before rendering the next page when
// the url changes

// THIS IS JUST SOME THEORETICAL PSEUDO CODE :)
class PendingNavDataLoader extends Component {
  state = {
    previousLocation: null,
    currentLocation: this.props.location
  };

  static getDerivedStateFromProps(props, state) {
    const currentLocation = props.location;
    const previousLocation = state.currentLocation;

    const navigated = currentLocation !== previousLocation;
    if (navigated) {
      // save the location so we can render the old screen
      return {
        previousLocation,
        currentLocation
      };
    }

    return null;
  }

  componentDidUpdate(prevProps) {
    const navigated = prevProps.location !== this.props.location;

    if (navigated) {
      // load data while the old screen remains
      loadNextData(routes, this.props.location).then(data => {
        putTheDataSomewhereRoutesCanFindIt(data);
        // clear previousLocation so the next screen renders
        this.setState({
          previousLocation: null
        });
      });
    }
  }

  render() {
    const { children, location } = this.props;
    const { previousLocation } = this.state;

    // use a controlled <Route> to trick all descendants into
    // rendering the old location
    return (
      <Route location={previousLocation || location} render={() => children} />
    );
  }
}

// wrap in withRouter
export default withRouter(PendingNavDataLoader);

/////////////
// somewhere at the top of your app
import routes from "./routes";

<BrowserRouter>
  <PendingNavDataLoader routes={routes}>
    {renderRoutes(routes)}
  </PendingNavDataLoader>
</BrowserRouter>;

@joacub
Copy link
Author

joacub commented Aug 6, 2020

@timdorr can you response ?

@kybarg
Copy link

kybarg commented Nov 14, 2021

@joacub This is short answer

- return (
-    <Route location={previousLocation || location} render={() => children} />
-  );
+ const element = useRoutes(routes, previousLocation || location);
+ return element
  )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants