我似乎找不到如何更新查询参数与反应路由器不使用<Link/>。hashHistory.push(url)似乎没有注册查询参数,而且似乎不能将查询对象或任何东西作为第二个参数传递。
如何将url从/shop/Clothes/dresses更改为/shop/Clothes/dresses?color=blue在反应路由器没有使用<链接>?
onChange函数真的是侦听查询更改的唯一方法吗?为什么不自动检测和响应查询更改-以参数更改的方式?
我似乎找不到如何更新查询参数与反应路由器不使用<Link/>。hashHistory.push(url)似乎没有注册查询参数,而且似乎不能将查询对象或任何东西作为第二个参数传递。
如何将url从/shop/Clothes/dresses更改为/shop/Clothes/dresses?color=blue在反应路由器没有使用<链接>?
onChange函数真的是侦听查询更改的唯一方法吗?为什么不自动检测和响应查询更改-以参数更改的方式?
当前回答
使用react-router v4、redux-thunk和react-router-redux(5.0.0-alpha.6)包的示例。
当用户使用搜索功能时,我希望他能够为相同的查询发送url链接给同事。
import { push } from 'react-router-redux';
import qs from 'query-string';
export const search = () => (dispatch) => {
const query = { firstName: 'John', lastName: 'Doe' };
//API call to retrieve records
//...
const searchString = qs.stringify(query);
dispatch(push({
search: searchString
}))
}
其他回答
约翰的答案是正确的。当我处理参数时,我还需要URLSearchParams接口:
this.props.history.push({
pathname: '/client',
search: "?" + new URLSearchParams({clientId: clientId}).toString()
})
你可能还需要用一个withRouter HOC来包装你的组件。export default with throuter (YourComponent);
// react-router-dom v6
// import
import { useNavigate, createSearchParams } from 'react-router-dom';
// useSearchParams hook
const [searchParams, setSearchParams] = useSearchParams();
// usage
const params: URLSearchParams = new URLSearchParams();
params.id = '123';
params.color = 'white';
// set new parameters
setSearchParams(params);
! !当心!!这将只更新当前页面上的查询参数,但您将无法导航回(浏览器返回btn)到以前的路由,因为此选项不会更改历史记录。要使此行为到位,请检查之前的答案:https://stackoverflow.com/users/6160270/rakesh-sharma的答案
在我的例子中,输入输入字段输出到浏览器的url作为查询字符串,使用React JS功能组件如下所示
import React, { useEffect, useState } from 'react'
import { useHistory } from 'react-router-dom'
const Search = () => {
const [query, setQuery] = useState('')
const history = useHistory()
const onChange = (e) => {
setQuery(e.target.value)
}
useEffect(() => {
const params = new URLSearchParams()
if (query) {
params.append('name', query)
} else {
params.delete('name')
}
history.push({ search: params.toString() })
}, [query, history])
return <input type="text" value={query} onChange={onChange} />
}
export default Search
浏览器URL查询
/搜索吗?name = query_here
对于React Router v6+,只需使用新的useSearchParams钩子(特别是setSearchParams):
const [searchParams, setSearchParams] = useSearchParams()
setSearchParams(`?${new URLSearchParams({ paramName: 'whatever' })}`)
对于React Router v5使用useHistory:
const history = useHistory()
history.push({
pathname: '/the-path',
search: `?${new URLSearchParams({ paramName: 'whatever' })}`
})
URLSearchParams只是一个可选的方便助手。
我目前在一个正在运行的项目中使用react-router v5,不容易迁移到v6。 我写了一个钩子,允许读取和修改一个URL参数,同时保持其他URL参数不变。 数组被视为逗号分隔值的列表: magnifying_glass ?产品=管,猎鹿帽
import { useCallback } from 'react';
import { useHistory } from 'react-router';
const getDecodedUrlParam = (name: string, locationSearch: string, _default?: any) => {
const params = deserialize(locationSearch);
const param = params[name];
if (_default && Array.isArray(_default)) {
return param
? param.split(',').map((v: string) => decodeURIComponent(v))
: _default;
}
return param ? decodeURIComponent(param) : _default;
};
const deserialize = (locationSearch: string): any => {
if (locationSearch.startsWith('?')) {
locationSearch = locationSearch.substring(1);
}
const parts = locationSearch.split('&');
return Object.fromEntries(parts.map((part) => part.split('=')));
};
const serialize = (params: any) =>
Object.entries(params)
.map(([key, value]) => `${key}=${value}`)
.join('&');
export const useURLSearchParam = (name: string, _default?: any) => {
const history = useHistory();
const value: any = getDecodedUrlParam(name, location.search, _default);
const _update = useCallback(
(value: any) => {
const params = deserialize(location.search);
if (Array.isArray(value)) {
params[name] = value.map((v) => encodeURIComponent(v)).join(',');
} else {
params[name] = encodeURIComponent(value);
}
history.replace({ pathname: location.pathname, search: serialize(params) });
},
[history, name]
);
const _delete = useCallback(() => {
const params = deserialize(location.search);
delete params[name];
history.replace({ pathname: location.pathname, search: serialize(params) });
}, [history, name]);
return [value, _update, _delete];
};