-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Closed
Labels
feature-requestUsed to close PRs that haven't gone through/been accepted the Proposal process yetUsed to close PRs that haven't gone through/been accepted the Proposal process yet
Description
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:
- navigate to
#/item/10001?filters=xxxx
- navigate to
#/randompage
// which clears the filter state. - 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>
Metadata
Metadata
Assignees
Labels
feature-requestUsed to close PRs that haven't gone through/been accepted the Proposal process yetUsed to close PRs that haven't gone through/been accepted the Proposal process yet