我有一条/cart
路由,接受两个称为validate
和email
的查询参数。仅在用户未登录时使用它们,而在用户登录时则不需要。在后一种情况下,我想将其从URL中删除。
这是我当前用于onEnter
路由的/cart
函数:
const requireCartLogin = (props, replace) => {
const { email, validate } = props.location.query;
// Exit process if the 'validate' query isn’t present.
if (typeof validate === 'undefined') { return; }
if (!isAuthenticated() || requiresReauthentication()) {
replace({
pathname: '/account/signin',
query: { step: 'signin' },
state: {
email: typeof email !== 'undefined' ? email : null,
auth: true,
next: '/cart'
}
});
} else if (isAuthenticated()) {
replace({
pathname: '/cart',
query: null
});
}
};
这是条件的第二部分,应该删除查询参数,但当前不起作用。我在这里想念什么?
答案 0 :(得分:0)
看看Dimitry Dushin的example
创建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);
请注意,这不适用于react-router
的> v4。
答案 1 :(得分:0)
react-router-dom
删除是最棘手的部分,因此首先您需要能够以合理的格式获取当前参数。
您可以通过useLocation
挂钩将搜索参数作为字符串获取。
但是使用这样的字符串会造成混淆,我更喜欢处理一个对象。
例如?filter=123&filter=something&page=1
将产生以下对象。
{
filter: ['123', 'something'],
page: ['1']
}
更容易操作。
因此,我们应该创建2个实用程序函数,一个将搜索字符串转换为上述对象,另一个将一个对象转换回搜索字符串。
toParamObject.js
const toParamObject = (queryString) => {
const params = new URLSearchParams(queryString);
let paramObject = {};
params.forEach((value, key) => {
if (paramObject[key]) {
paramObject = {
...paramObject,
[key]: [
...paramObject[key],
value,
],
};
} else {
paramObject = {
...paramObject,
[key]: [value],
};
}
});
return paramObject;
};
toQueryString.js
const toQueryString = (paramObject) => {
let queryString = '';
Object.entries(paramObject).forEach(([paramKey, paramValue]) => {
if (paramValue.length === 0) {
return;
}
queryString += '?';
paramValue.forEach((value, index) => {
if (index > 0) {
queryString += '&';
}
queryString += `${paramKey}=${value}`;
});
});
// This is kind of hacky, but if we push '' as the route, we lose
// our page, and base path etc.
// So instead.. pushing a '?' just removes all the current query strings
return queryString !== '' ? queryString : '?';
};
// search is from useLocation, and we can just pass in the name of the param we want
const get = (key) => toParamObject(search)[key] || [];
const remove = (key, value) => {
// First get the current params get()
const thisParam = get(param).filter((val) => val !== value);
const newParamObject = {
...toParamObject(search), // from useLocation
[param]: thisParam,
};
push(`${toQueryString(newParamObject)}`); // from useHistory
};
答案 2 :(得分:0)
我搜索了一段时间,然后意识到自己需要做的就是像往常一样使用历史记录来推送到url(没有参数):
// this piece of code is in /app/settings/account
React.useEffect(() => {
let params = queryString.parse(location.search)
if (params && params.code) {
doSomething(params.code)
history.push('/app/settings/account')
}
}, [])