我似乎找不到如何更新查询参数与反应路由器不使用<Link/>。hashHistory.push(url)似乎没有注册查询参数,而且似乎不能将查询对象或任何东西作为第二个参数传递。

如何将url从/shop/Clothes/dresses更改为/shop/Clothes/dresses?color=blue在反应路由器没有使用<链接>?

onChange函数真的是侦听查询更改的唯一方法吗?为什么不自动检测和响应查询更改-以参数更改的方式?


当前回答

你可以使用钩子useHistory 确保你使用的是基于函数的组件 在顶部导入这个

import {useHistory} from "react-router-dom"

在你的组件中,

const history = useHistory()
history.push({
    pathname: window.location.pathname,
    search: '?color=blue'
})

其他回答

使用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
    }))
}

React-router-dom v5解决方案

  import { useHistory } from 'react-router-dom'; 
  const history = useHistory(); // useHistory hook inside functional component  
    
  history.replace({search: (new URLSearchParams({activetab : 1})).toString()});

建议使用URLSearchParams,因为它可以在编码和解码查询参数时处理查询参数中的空格和特殊字符

    new URLSearchParams({'active tab':1 }).toString() // 'active+tab=1'
    new URLSearchParams('active+tab=1').get('active tab') // 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;
                }, {}
            )
        : {}
};

我做了一个简单的钩子来减轻工作。

让我们想象一下你的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>
    )
}
// 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的答案