คุณอัปเดตพารามิเตอร์การสืบค้นโดยทางโปรแกรมใน react-router ได้อย่างไร


119

ฉันไม่สามารถดูเหมือนจะหาวิธีการปรับปรุง params <Link/>แบบสอบถามที่มีการตอบสนองเราเตอร์โดยไม่ต้องใช้ hashHistory.push(url)ดูเหมือนจะไม่ลงทะเบียนพารามิเตอร์การสืบค้นและดูเหมือนว่าคุณไม่สามารถส่งผ่านวัตถุแบบสอบถามหรืออะไรก็ได้เป็นอาร์กิวเมนต์ที่สอง

คุณจะเปลี่ยน url จาก/shop/Clothes/dressesเป็น/shop/Clothes/dresses?color=blueใน react-router โดย<Link>ไม่ใช้ได้อย่างไร?

และonChangeฟังก์ชั่นเป็นวิธีเดียวที่จะรับฟังการเปลี่ยนแปลงคำค้นหาหรือไม่ เหตุใดจึงไม่ตรวจพบการเปลี่ยนแปลงการค้นหาโดยอัตโนมัติและตอบสนองต่อวิธีการเปลี่ยนแปลงพารามิเตอร์


คุณควรใช้ Singleton ประวัติศาสตร์ตามที่อ้างถึงในคำถามนี้
Joseph Combs

คำตอบ:


144

ภายในpushวิธีการของhashHistoryคุณสามารถระบุพารามิเตอร์การค้นหาของคุณ ตัวอย่างเช่น

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

หรือ

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

คุณสามารถตรวจสอบที่เก็บนี้เพื่อดูตัวอย่างเพิ่มเติมเกี่ยวกับการใช้history


2
! น่ากลัว ยังมีการส่งต่อวัตถุแบบสอบถาม {color: blue, size: 10} แทนสตริงหรือไม่
claireablani

1
@claireablani ปัจจุบันฉันไม่คิดว่าจะรองรับ
John F.

1
@claireablani คุณสามารถลองสิ่งนี้router.push({ pathname: '/path', state: { color: 'blue', size: 10 }, });
MichelH

4
เพียงเพื่อความชัดเจนสิ่งนี้ใช้ไม่ได้ใน react router v4 อีกต่อไป สำหรับสิ่งนั้นโปรดดูคำตอบของ @kristupas-repeatčka
dkniffin

14
เวลาที่ไม่แน่นอนที่เราอาศัยอยู่
Kristupas Repečka

39

ตัวอย่างการใช้แพ็คเกจ 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
    }))
}

8
react-router-reduxเลิกใช้แล้ว
vsync

ฉันคิดว่าตอนนี้ต้องทำได้โดยการแสดง<Redirect>แท็กลิงก์ไปยัง หน้าเอกสาร
TKAB

2
คุณสามารถห่อส่วนประกอบของคุณไว้ในwithReducerHOC ซึ่งจะทำให้คุณมีhistoryเสา history.push({ search: querystring }และจากนั้นคุณสามารถเรียกใช้
sasklacz

แต่react-router-reduxคุณสามารถใช้connected-react-routerสิ่งที่ไม่ได้เลิกใช้งานแทน
Søren Boisen

29

คำตอบของยอห์นถูกต้อง เมื่อฉันจัดการกับพารามิเตอร์ฉันต้องใช้URLSearchParamsอินเทอร์เฟซด้วย:

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

คุณอาจต้องห่อส่วนประกอบของคุณด้วยwithRouterHOC เช่น export default withRouter(YourComponent);.


1
withRouterเป็น HOC ไม่ใช่มัณฑนากร
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

จากDimitriDushkin บน 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);
};

หรือ

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

การใช้โมดูลสตริงการสืบค้นเป็นสิ่งที่แนะนำเมื่อคุณต้องการโมดูลเพื่อแยกวิเคราะห์สตริงการสืบค้นของคุณอย่างง่ายดาย

http: // localhost: 3000 โทเค็น = xxx-xxx-xxx

componentWillMount() {
    var query = queryString.parse(this.props.location.search);
    if (query.token) {
        window.localStorage.setItem("jwt", query.token);
        store.dispatch(push("/"));
    }
}

ที่นี่ฉันกำลังเปลี่ยนเส้นทางกลับไปยังไคลเอนต์ของฉันจากเซิร์ฟเวอร์ Node.js หลังจากตรวจสอบสิทธิ์ Google-Passport สำเร็จซึ่งจะเปลี่ยนเส้นทางกลับด้วยโทเค็นเป็นพารามิเตอร์การค้นหา

ฉันกำลังแยกกับโมดูลแบบสอบถามสตริงบันทึกและปรับปรุง params แบบสอบถามใน url ด้วยการกดจากตอบสนองเตอร์-Redux


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

1

นอกจากนี้ยังสามารถเขียนด้วยวิธีนี้

this.props.history.push(`${window.location.pathname}&page=${pageNumber}`)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.