我正在尝试弄清楚如何使用 useNavigate
挂钩来导航/重定向用户并更新查询参数(如果有)。
我创建了一个自定义的 useNavigateParams
钩子,我从几个不同的 SO 答案中改编了它,它看起来像这样:
import { generatePath, ParamKeyValuePair, useNavigate } from 'react-router-dom';
import { getSearchParams, isObjectEmpty } from 'src/utils';
type TUseNavigateParams = {
uri: string;
params?: Record<string, unknown>;
};
export default function useNavigateParams() {
const navigate = useNavigate();
return ({ uri, params = {} }: TUseNavigateParams) => {
let path = uri;
if (!isObjectEmpty(params)) {
path += generatePath('?:queryString', {
uri,
queryString: getSearchParams(Object.entries(params) as ParamKeyValuePair[]),
});
}
console.log('decoded', decodeURIComponent(path));
navigate(path);
};
}
const getSearchParams = (params: ParamKeyValuePair[]) => {
let searchParams = '';
params.forEach((param, index) => {
const localDestructured = Object.entries(param[1]);
console.log('localDestructured', localDestructured);
searchParams += createSearchParams({
[param[0]]: JSON.stringify({ [localDestructured[0][0]]: localDestructured[0][1] }),
});
});
return createSearchParams(searchParams).toString();
};
这里的想法是,我基本上会在整个项目中始终使用 useNavigateParams
,而不是 useNavigate
。
我的问题如下。像下面这样简单的东西就可以正常工作:
const uri = 'myPath'
const filter = 'active'
const params = { filter: { status: filter } }
navigate({
uri,
params,
})
这将打印,
myPath?filter={"status":"active"}
但是做类似的事情,
const uri = 'myPath'
const filter = 'active'
const params = { filter: { status: filter, hello: 'world' } }
navigate({
uri,
params,
})
不会打印,
myPath?filter={"status":"active", "hello":"world"}
我知道我可以添加另一个 forEach
或找出一些笨拙的方法,但它看起来如此庞大,而且它实际上无法重复使用/动态。
我希望能够传递某种参数,例如,
const uri = 'myPath'
const filter = 'active'
const params = { filter: { status: filter, hello: 'world' }, foo: 'bar', baz: { node: 'leaf' } }
navigate({
uri,
params,
})
并期望输出为:
myPath?filter={"status":"active", "hello":"world"}&foo=bar&baz={"node":"leaf"}
是否有更简洁、更可靠的方法来实现这样的结果?
答案 0 :(得分:0)
我已经在使用 axios
,所以我最终使用了 getUri
:
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
type TUseNavigateParams = {
uri: string;
params?: Record<string, unknown>;
};
export default function useNavigateParams() {
const navigate = useNavigate();
return ({ uri, params = {} }: TUseNavigateParams) => {
const path = axios.getUri({ url: uri, params });
navigate(path);
};
}