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

[Feature]: <Routes> onChange props please #9688

Closed
AntiMoron opened this issue Dec 6, 2022 · 1 comment
Closed

[Feature]: <Routes> onChange props please #9688

AntiMoron opened this issue Dec 6, 2022 · 1 comment
Labels

Comments

@AntiMoron
Copy link

AntiMoron commented Dec 6, 2022

What is the new or updated feature that you are suggesting?

interface RouterState {
  location: Location;
  params: Params;
}

interface RoutesProps {
  children?: React.ReactNode;
  location?: Partial<Location> | string;
  // I'm going to add this
  onChange?: (prevState: RouterState, nextState: RouterState) => void;
}

<Routes onChange={(prevState, nextState) => {
   // prevState.location; same as useLocation
  // prevState.params; same as useParams
}}>
  <Route element={<XX1 />} route="/xxx1" />
  <Route element={<XX2 />} route="/xxx2" />
  <Route element={<XX3 />} route="/xxx3" />
</Routes>

Why should this feature be included?

What is not enough?

With the current API, you cannot detect path changing before it actually happens. You can only know it afterwards with useLocation and useEffect.

Why I need it, show some scenarios:

Usually, we need to know when the route changes as we need to fetch API results with different parameters. We'll code like this:

// <Route  element={<DetailPage />} path="/item/:itemId" />
// localhost:3000/#/item/10001?filters={"price":">100$"}

const location = useLocation();
const params = useParams();

useEffect(() => {
  const itemId =  params.itemId;
  const pathname = location.pathname;
  // get extra params from hash query, pass it as a request parameter.
  request('/some/api/for/itemDetial', parse(location.search).filters).then((data) => { // filters as a parameter.
    setState(data);
  });
}, [location, params]);

As there's some new data flow library as recoil by Facebook which is based on observer pattern, requests are usually bound with state changes, like:

// atom.ts
const filter = atom({ key: 'filterParamKey', default: undefined });
const getDetail = selector({
  key: 'getDetailSelector',
  get: async ({ get }) => {  // this function will be triggered for every atom involved in with the `get` method changes.
    const filterValue = get(filter);
    return await request('/some/api/for/itemDetial', filterValue);
  }
});

// component.tsx
const location = useLocation();
const params = useParams();
const setFilterState = useSetRecoilState(filter); // components just need to focus on setting values with `recoil`.
useEffect(() => {
  setFilterState(parse(location.search).filters);
}, [location, params]);

In this case, request is triggered instantly when the filter state changes.
If you route as below:

  1. navigate to #/item/10001?filters=xxxx
  2. navigate to #/randompage // which clears the filter state.
  3. click prev of the browser and find out filter parameter is lost.

How to fix it with onChange property

const location = useLocation();
const params = useParams();
const setFilterState = useSetRecoilState(filter); // components just need to focus on setting values with `recoil`.
return <Routes onChange={(prev, next) => {
  setFilterState(parse(next.location.search).filters);
}}>

</Routes>
@AntiMoron AntiMoron changed the title [Feature]: <Router> onChange props; [Feature]: <Routes> onChange props please Dec 6, 2022
@brophdawg11
Copy link
Contributor

I think this will be covered by the Events Proposal, so I'm going to close this out and link to it from there.

If there's a separate aspect to be considered, please open a Proposal over in the Discussions tab so it can go through our new Open Development process. Thanks!

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

No branches or pull requests

2 participants