你如何以编程方式更新react-router中的查询参数?

cla*_*ani 87 reactjs react-router

我似乎无法找到如何使用react-router更新查询参数而不使用<Link/>.hashHistory.push(url)似乎没有注册查询参数,似乎你不能将查询对象或任何东西作为第二个参数传递.

如何从更改URL /shop/Clothes/dresses,以/shop/Clothes/dresses?color=blue在反应路由器没有使用<Link>

并且onChange函数真的是监听查询更改的唯一方法吗?为什么不自动检测到查询更改并对响应更改的方式做出反应?

Joh*_* F. 105

push方法中hashHistory,您可以指定查询参数.例如,

history.push({
  pathname: '/dresses',
  search: '?color=blue'
})
Run Code Online (Sandbox Code Playgroud)

要么

history.push('/dresses?color=blue')
Run Code Online (Sandbox Code Playgroud)

您可以查看此存储库以获取有关使用的其他示例history

  • 我们生活的不稳定时期 (8认同)
  • 只是为了澄清,这不再适用于路由器v4.为此,请参阅@ kristupas-repečka的答案 (4认同)
  • 真棒!无论如何传递查询对象{color:blue,size:10}而不是字符串? (2认同)
  • @claireablani 目前,我认为不支持 (2认同)
  • @claireablani你可以尝试这个 `router.push({ pathname: '/path', state: { color: 'blue', size: 10 }, });` (2认同)

Kri*_*čka 30

使用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
    }))
}
Run Code Online (Sandbox Code Playgroud)

  • `react-router-redux`已过时 (4认同)
  • 您可以将您的组件包装在 `withReducer` HOC 中,这将为您提供 `history` 道具。然后你可以运行`history.push({ search: querystring }`。 (2认同)

Tra*_*oud 17

对于 React Router,v6+只需使用新的useSearchParams钩子(特别是setSearchParams):

const [searchParams, setSearchParams] = useSearchParams()

setSearchParams(`?${new URLSearchParams({ paramName: 'whatever' })}`)

Run Code Online (Sandbox Code Playgroud)

对于 React Routerv5使用useHistory

const history = useHistory()

history.push({
    pathname: '/the-path',
    search: `?${new URLSearchParams({ paramName: 'whatever' })}`
})
Run Code Online (Sandbox Code Playgroud)

注意: URLSearchParams只是一个可选(推荐!)的便利助手,但您也可以仅使用带有 url 参数的原始字符串。


spe*_*edy 13

约翰的回答是正确的.当我处理params我还需要URLSearchParams接口:

this.props.history.push({
    pathname: '/client',
    search: "?" + new URLSearchParams({clientId: clientId}).toString()
})
Run Code Online (Sandbox Code Playgroud)

您可能还需要使用withRouter装饰器包装组件,例如.export default withRouter(YourComponent);.

  • 这里不需要使用 .toString() ,因为前面加上问号会自动强制它。 (2认同)

Rak*_*rma 11

使用React Router V6我们可以这样实现

import { useNavigate, createSearchParams } from 'react-router-dom';

/* In React Component */
const navigate = useNavigate();
const params = {
  color: 'blue',
};
const options = {
  pathname: '/shop/Clothes/dresses',
  search: `?${createSearchParams(params)}`,
};
navigate(options, { replace: true });
Run Code Online (Sandbox Code Playgroud)


Kou*_*Das 9

您可以使用钩子useHistory 确保您使用的是function基于组件在顶部导入它

import {useHistory} from "react-router-dom"
Run Code Online (Sandbox Code Playgroud)

在你的组件中,

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


小智 7

    for react-router v4.3, 
Run Code Online (Sandbox Code Playgroud)
 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
Run Code Online (Sandbox Code Playgroud)


Vir*_*ngh 7

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()});
Run Code Online (Sandbox Code Playgroud)

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

    new URLSearchParams({'active tab':1 }).toString() // 'active+tab=1'
    new URLSearchParams('active+tab=1').get('active tab') // 1
Run Code Online (Sandbox Code Playgroud)


Cra*_*ues 5

您可以使用替换功能而不是在每次更改时推送新路由

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} />
}
Run Code Online (Sandbox Code Playgroud)

这会保留历史记录,而不是在每次更改时都推新路径