我似乎无法找到如何使用react-router更新查询参数而不使用<Link/>
。 hashHistory.push(url)
似乎没有注册查询参数,并且您似乎不能将查询对象或任何内容作为第二个参数传递。
如何在不使用/shop/Clothes/dresses
的情况下将react-/shop/Clothes/dresses?color=blue
中的网址更改为<Link>
?
并且onChange
函数真的是监听查询更改的唯一方法吗?为什么不自动检测到查询更改并对参数更改的方式做出反应?
答案 0 :(得分:78)
在push
的{{1}}方法中,您可以指定查询参数。例如,
hashHistory
或
history.push({
pathname: '/dresses',
search: '?color=blue'
})
有关使用history.push('/dresses?color=blue')
答案 1 :(得分:29)
使用react-router v4,redux-thunk和react-router-redux(5.0.0-alpha.6)包的示例。
当用户使用搜索功能时,我希望他能够将同一查询的网址链接发送给同事。
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
}))
}
答案 2 :(得分:11)
John's answer是正确的。在处理参数时,我还需要URLSearchParams
界面:
this.props.history.push({
pathname: '/client',
search: "?" + new URLSearchParams({clientId: clientId}).toString()
})
您可能还需要使用withRouter
装饰器将组件包装起来,例如。 export default withRouter(YourComponent);
。
答案 3 :(得分:2)
import { browserHistory } from 'react-router';
/**
* @param {Object} query
*/
export const addQuery = (query) => {
const location = Object.assign({}, browserHistory.getCurrentLocation());
Object.assign(location.query, query);
// or simple replace location.query if you want to completely change params
browserHistory.push(location);
};
/**
* @param {...String} queryNames
*/
export const removeQuery = (...queryNames) => {
const location = Object.assign({}, browserHistory.getCurrentLocation());
queryNames.forEach(q => delete location.query[q]);
browserHistory.push(location);
};
或
import { withRouter } from 'react-router';
import { addQuery, removeQuery } from '../../utils/utils-router';
function SomeComponent({ location }) {
return <div style={{ backgroundColor: location.query.paintRed ? '#f00' : '#fff' }}>
<button onClick={ () => addQuery({ paintRed: 1 })}>Paint red</button>
<button onClick={ () => removeQuery('paintRed')}>Paint white</button>
</div>;
}
export default withRouter(SomeComponent);
答案 4 :(得分:2)
当您需要一个模块来轻松解析查询字符串时,建议使用query-string模块。
componentWillMount() {
var query = queryString.parse(this.props.location.search);
if (query.token) {
window.localStorage.setItem("jwt", query.token);
store.dispatch(push("/"));
}
}
在这里,我在成功进行Google Passport身份验证后从Node.js服务器重定向回我的客户端,该身份验证重定向回来时使用令牌作为查询参数。
我使用查询字符串模块解析它,保存它并使用react-router-redux的推送更新网址中的查询参数。
答案 5 :(得分:2)
您可以使用替换功能,而不是在每次更改时推送一条新路线
import React from 'react';
import { useHistory, useLocation } from 'react-router';
const MyComponent = ()=>{
const history = useHistory();
const location = useLocation();
const onChange=(event)=>{
const {name, value} = event?.target;
const params = new URLSearchParams({[name]: value });
history.replace({ pathname: location.pathname, search: params.toString() });
}
return <input name="search" onChange={onChange} />
}
这会保留历史记录,而不是在每次更改时都推新路径
答案 6 :(得分:1)
我希望您使用ES6
样式的以下函数:
getQueryStringParams = query => {
return query
? (/^[?#]/.test(query) ? query.slice(1) : query)
.split('&')
.reduce((params, param) => {
let [key, value] = param.split('=');
params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
return params;
}, {}
)
: {}
};
答案 7 :(得分:0)
for 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>;
}
```
// To know more on URLSearchParams from
[Mozilla:][1]
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"
[1]: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
答案 8 :(得分:0)
也可以这样写
this.props.history.push(`${window.location.pathname}&page=${pageNumber}`)
答案 9 :(得分:0)
在我的例子中,输入字段将其作为查询字符串输出到浏览器的 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 查询
/search?name=query_here