我似乎找不到如何更新查询参数与反应路由器不使用<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.3
const addQuery = (key, value) => {
let pathname = props.location.pathname;
// returns path: '/app/books'
let searchParams = new URLSearchParams(props.location.search);
// returns the existing query string: '?type=fiction&author=fahid'
searchParams.set(key, value);
this.props.history.push({
pathname: pathname,
search: searchParams.toString()
});
};
const removeQuery = (key) => {
let pathname = props.location.pathname;
// returns path: '/app/books'
let searchParams = new URLSearchParams(props.location.search);
// returns the existing query string: '?type=fiction&author=fahid'
searchParams.delete(key);
this.props.history.push({
pathname: pathname,
search: searchParams.toString()
});
};
function SomeComponent({ location }) {
return <div>
<button onClick={ () => addQuery('book', 'react')}>search react books</button>
<button onClick={ () => removeQuery('book')}>remove search</button>
</div>;
}
要了解更多关于URLSearchParams:
var paramsString = "q=URLUtils.searchParams&topic=api";
var searchParams = new URLSearchParams(paramsString);
//Iterate the search parameters.
for (let p of searchParams) {
console.log(p);
}
searchParams.has("topic") === true; // true
searchParams.get("topic") === "api"; // true
searchParams.getAll("topic"); // ["api"]
searchParams.get("foo") === null; // true
searchParams.append("topic", "webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
searchParams.set("topic", "More webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
searchParams.delete("topic");
searchParams.toString(); // "q=URLUtils.searchParams"
其他回答
当你需要一个模块来轻松地解析你的查询字符串时,推荐使用query-string模块。
http://localhost:3000?token=xxx-xxx-xxx
componentWillMount() {
var query = queryString.parse(this.props.location.search);
if (query.token) {
window.localStorage.setItem("jwt", query.token);
store.dispatch(push("/"));
}
}
在这里,我从Node.js服务器重定向回我的客户端后,成功的Google-Passport身份验证,这是重定向回令牌作为查询参数。
我用query-string模块解析它,保存它并更新url中的查询参数,从react-router-redux推送。
约翰的答案是正确的。当我处理参数时,我还需要URLSearchParams接口:
this.props.history.push({
pathname: '/client',
search: "?" + new URLSearchParams({clientId: clientId}).toString()
})
你可能还需要用一个withRouter HOC来包装你的组件。export default with throuter (YourComponent);
对于react-router v4.3
const addQuery = (key, value) => {
let pathname = props.location.pathname;
// returns path: '/app/books'
let searchParams = new URLSearchParams(props.location.search);
// returns the existing query string: '?type=fiction&author=fahid'
searchParams.set(key, value);
this.props.history.push({
pathname: pathname,
search: searchParams.toString()
});
};
const removeQuery = (key) => {
let pathname = props.location.pathname;
// returns path: '/app/books'
let searchParams = new URLSearchParams(props.location.search);
// returns the existing query string: '?type=fiction&author=fahid'
searchParams.delete(key);
this.props.history.push({
pathname: pathname,
search: searchParams.toString()
});
};
function SomeComponent({ location }) {
return <div>
<button onClick={ () => addQuery('book', 'react')}>search react books</button>
<button onClick={ () => removeQuery('book')}>remove search</button>
</div>;
}
要了解更多关于URLSearchParams:
var paramsString = "q=URLUtils.searchParams&topic=api";
var searchParams = new URLSearchParams(paramsString);
//Iterate the search parameters.
for (let p of searchParams) {
console.log(p);
}
searchParams.has("topic") === true; // true
searchParams.get("topic") === "api"; // true
searchParams.getAll("topic"); // ["api"]
searchParams.get("foo") === null; // true
searchParams.append("topic", "webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
searchParams.set("topic", "More webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
searchParams.delete("topic");
searchParams.toString(); // "q=URLUtils.searchParams"
我目前在一个正在运行的项目中使用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];
};
我做了一个简单的钩子来减轻工作。
让我们想象一下你的url是这样的: /搜索吗?起源=主页= 1
function useUrl(param: string) {
const history = useHistory()
const { search, pathname } = useLocation()
const url = new URLSearchParams(search)
const urlParam = url.get(param)
const [value, setValue] = useState(urlParam !== null ? urlParam : '')
function _setValue(val: string){
url.set(param, val)
history.replace({ pathname, search: url.toString() });
setValue(val)
}
return [value, _setValue]
}
那么实际使用情况:
function SearchPage() {
const [origin] = useUrl("origin")
const [page, setPage] = useUrl("page")
return (
<div>
<p>Return to: {origin}</p>
<p>Current Page: {page}</p>
</div>
)
}