Làm cách nào để cập nhật lập trình các tham số truy vấn trong bộ định tuyến phản ứng?


117

Tôi dường như không thể tìm thấy cách cập nhật các tham số truy vấn với react-router mà không sử dụng <Link/>. hashHistory.push(url)dường như không đăng ký tham số truy vấn và có vẻ như bạn không thể chuyển một đối tượng truy vấn hoặc bất kỳ thứ gì làm đối số thứ hai.

Làm thế nào để bạn thay đổi url từ /shop/Clothes/dressesđể /shop/Clothes/dresses?color=bluetrong phản ứng-router mà không sử dụng <Link>?

Và một onChangehàm thực sự là cách duy nhất để lắng nghe các thay đổi truy vấn? Tại sao các thay đổi truy vấn không được tự động phát hiện và phản ứng theo cách mà các thay đổi tham số là?


bạn nên sử dụng singleton lịch sử như được đề cập trong câu hỏi này
Joseph Combs

Câu trả lời:


143

Trong pushphương thức của hashHistory, bạn có thể chỉ định các tham số truy vấn của mình. Ví dụ,

history.push({
  pathname: '/dresses',
  search: '?color=blue'
})

hoặc là

history.push('/dresses?color=blue')

Bạn có thể xem kho lưu trữ này để biết thêm các ví dụ về cách sử dụnghistory


2
tuyệt vời! Có cách nào để chuyển một đối tượng truy vấn {color: blue, size: 10} thay vì một chuỗi không?
claireablani

1
@claireablani Hiện nay, tôi không nghĩ rằng được hỗ trợ
John F.

1
@claireablani bạn có thể thử cái nàyrouter.push({ pathname: '/path', state: { color: 'blue', size: 10 }, });
MichelH

4
Chỉ để làm rõ, điều này không còn hoạt động trong bộ định tuyến phản ứng v4. Cho rằng, nhìn thấy câu trả lời @ kristupas-repečka của
dkniffin

13
lần không ổn định chúng ta đang sống.
Kristupas Repečka

39

Ví dụ sử dụng gói react-router v4, redux-thunk và react-router-redux (5.0.0-alpha.6).

Khi người dùng sử dụng tính năng tìm kiếm, tôi muốn anh ta có thể gửi liên kết url cho cùng một truy vấn đến một đồng nghiệp.

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

8
react-router-reduxkhông được dùng nữa
vsync,

Tôi nghĩ rằng điều này bây giờ phải được thực hiện bằng cách hiển thị <Redirect>thẻ, liên kết đến trang tài liệu
TKAB

2
Bạn chỉ có thể bọc thành phần của mình trong withReducerHOC, điều này sẽ cung cấp cho bạn chỗ dựa history. Và sau đó bạn có thể chạy history.push({ search: querystring }.
sasklacz

Thay vào đó react-router-redux, bạn có thể sử dụng connected-react-routercái không bị phản đối.
Søren Boisen

29

Câu trả lời của John là đúng. Khi xử lý các thông số, tôi cũng cần URLSearchParamsgiao diện:

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

Bạn cũng có thể cần bọc thành phần của mình bằng withRouterHOC, ví dụ. export default withRouter(YourComponent);.


1
withRouterlà một HOC, không phải là một trang trí
Luis Paulo

4
    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

3

Từ DimitriDushkin trên GitHub :

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);
};

hoặc là

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);

2

Sử dụng mô-đun chuỗi truy vấn là mô-đun được khuyến nghị khi bạn cần một mô-đun để phân tích chuỗi truy vấn của mình một cách dễ dàng.

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("/"));
    }
}

Tại đây, tôi đang chuyển hướng trở lại ứng dụng khách của mình từ máy chủ Node.js sau khi xác thực thành công Google-Passport, đang chuyển hướng trở lại với mã thông báo dưới dạng tham số truy vấn.

Tôi đang phân tích cú pháp nó bằng mô-đun chuỗi truy vấn, lưu nó và cập nhật các tham số truy vấn trong url với sự thúc đẩy từ react-router-redux .


1

Tôi thích bạn sử dụng chức năng dưới đây là ES6phong cách:

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;
                }, {}
            )
        : {}
};

1

Nó cũng có thể được viết theo cách này

this.props.history.push(`${window.location.pathname}&page=${pageNumber}`)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.