การรับพารามิเตอร์การสืบค้นจากส่วนแฮชของเราเตอร์ปฏิกิริยา


112

ฉันใช้ react และ react-router สำหรับแอปพลิเคชันของฉันทางฝั่งไคลเอ็นต์ ฉันไม่สามารถหาวิธีรับพารามิเตอร์การค้นหาต่อไปนี้จาก url เช่น:

http://xmen.database/search#/?status=APPROVED&page=1&limit=20

เส้นทางของฉันมีลักษณะเช่นนี้ (ฉันรู้เส้นทางผิดโดยสิ้นเชิง):

var routes = (
<Route>
    <DefaultRoute handler={SearchDisplay}/>
    <Route name="search" path="?status=:status&page=:page&limit=:limit" handler={SearchDisplay}/>
    <Route name="xmen" path="candidate/:accountId" handler={XmenDisplay}/>
</Route>
);

เส้นทางของฉันใช้งานได้ดี แต่ฉันไม่แน่ใจว่าจะจัดรูปแบบเส้นทางเพื่อให้ได้พารามิเตอร์ที่ฉันต้องการอย่างไร ขอบคุณความช่วยเหลือใด ๆ เกี่ยวกับเรื่องนี้!


ฉันมองไปรอบ ๆ และพบเพียงตัวอย่างของการแยกพารามิเตอร์สตริงการสืบค้นภายในคอมโพเนนต์เท่านั้นgetCurrentQuery
Cory Danielson


คุณสามารถใช้willTransitionToขอเกี่ยวกับตัวจัดการของคุณ ได้รับพารามิเตอร์สตริงการสืบค้น github.com/rackt/react-router/commit/…
Cory Danielson

นอกจากนี้ที่นี่สำหรับเอกสารเกี่ยวกับตะขอการเปลี่ยนแปลง: github.com/rackt/react-router/blob/master/docs/api/components/…คุณควรตอบคำถามนี้ด้วยวิธีแก้ปัญหาของคุณเมื่อคุณคิดออกแล้ว ฉันแน่ใจว่าคุณจะไม่ใช่คนสุดท้ายที่ต้องเจอกับสถานการณ์นี้
Cory Danielson

คำตอบ:


133

หมายเหตุ: คัดลอก / วางจากความคิดเห็น อย่าลืมชอบโพสต์ต้นฉบับ!

เขียนใน es6 และใช้ react 0.14.6 / react-router 2.0.0-rc5 ฉันใช้คำสั่งนี้เพื่อค้นหาพารามิเตอร์แบบสอบถามในส่วนประกอบของฉัน:

this.props.location.query

สร้างแฮชของพารามิเตอร์การสืบค้นที่มีอยู่ทั้งหมดใน url

อัปเดต:

สำหรับ React-Router v4 ดูคำตอบนี้ โดยทั่วไปใช้this.props.location.searchเพื่อรับสตริงการสืบค้นและแยกวิเคราะห์ด้วยquery-stringแพ็คเกจหรือURLSearchParams :

const params = new URLSearchParams(paramsString); 
const tags = params.get('tags');

2
มันไม่มีทางเหมือน React-router 1.x แล้ว 2.x ////
Peter Aron Zentai

7
สำหรับปีเตอร์ตัวอย่างนี้ล้าสมัย: ดูstackoverflow.com/a/35005474/298073
btown

2
queryดูเหมือนว่าจะหายไปใน React Router 4. github.com/ReactTraining/react-router/issues/…
Sung Cho

57

เก่า (ก่อน v4):

เขียนใน es6 และใช้ react 0.14.6 / react-router 2.0.0-rc5 ฉันใช้คำสั่งนี้เพื่อค้นหาพารามิเตอร์แบบสอบถามในส่วนประกอบของฉัน:

this.props.location.query

สร้างแฮชของพารามิเตอร์การสืบค้นที่มีอยู่ทั้งหมดใน url

อัปเดต (ตอบสนองเราเตอร์ v4 +):

this.props.location.query ใน React Router 4 ถูกลบออก (ปัจจุบันใช้ v4.1.1) เพิ่มเติมเกี่ยวกับปัญหาที่นี่: https://github.com/ReactTraining/react-router/issues/4410

ดูเหมือนว่าพวกเขาต้องการให้คุณใช้วิธีของคุณเองในการแยกวิเคราะห์พารามิเตอร์การสืบค้นโดยใช้ไลบรารีนี้เพื่อเติมเต็มช่องว่าง: https://github.com/sindresorhus/query-string


2
ฉันได้ทดสอบด้วย React 0.14.8 แล้วและคำตอบของคุณไม่สามารถแสดงผลได้: error TypeError: Cannot read property 'location' of undefined:: |
Thomas Modeneis

3
เฮ้ @ThomasModeneis นี่คือองค์ประกอบหลักที่สูงที่สุดที่เราเตอร์ของคุณกำลังแสดงผลใช่หรือไม่? หรือเป็นส่วนประกอบลูก? ถ้าฉันจำไม่ผิดคุณต้องส่ง this.props.location.query ไปยังส่วนประกอบลูกของคุณจากองค์ประกอบหลักที่เราเตอร์แสดงผลสิ่งเดียวที่ฉันคิดได้จากส่วนบนสุดของหัวฉัน
Marrs

55

react-router v4คำตอบดังกล่าวข้างต้นจะไม่ทำงานใน นี่คือสิ่งที่ฉันทำเพื่อแก้ปัญหา -

ขั้นแรกให้ติดตั้งสตริงการสืบค้นซึ่งจำเป็นสำหรับการแยกวิเคราะห์

npm install -save query-string

ตอนนี้ในองค์ประกอบที่กำหนดเส้นทางคุณสามารถเข้าถึงสตริงแบบสอบถามที่ไม่แยกวิเคราะห์ได้เช่นนี้

this.props.location.search

คุณสามารถตรวจสอบข้ามได้โดยเข้าสู่ระบบคอนโซล

ในที่สุดก็แยกวิเคราะห์เพื่อเข้าถึงพารามิเตอร์การค้นหา

const queryString = require('query-string');
var parsed = queryString.parse(this.props.location.search);
console.log(parsed.param); // replace param with your own 

ดังนั้นหากแบบสอบถามเป็นอย่างไร ?hello=world

console.log(parsed.hello) จะเข้าสู่ระบบ world


16
หรือไม่มี lib: const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));(ต้องการ polyfill สำหรับเบราว์เซอร์รุ่นเก่า)
Ninh Pham

สิ่งนี้ควรได้ผลเมื่อฉันสร้างแอปพลิเคชันใช่ไหม
Walter

16

อัปเดต 2017.12.25

"react-router-dom": "^4.2.2"

url เช่น

BrowserHistory: http://localhost:3000/demo-7/detail/2?sort=name

HashHistory: http://localhost:3000/demo-7/#/detail/2?sort=name

ด้วยการอ้างอิงสตริงการสืบค้น :

this.id = props.match.params.id;
this.searchObj = queryString.parse(props.location.search);
this.from = props.location.state.from;

console.log(this.id, this.searchObj, this.from);

ผล:

2 {sort: "name"} home


"react-router": "^2.4.1"

URL เช่น http://localhost:8080/react-router01/1?name=novaline&age=26

const queryParams = this.props.location.query;

queryParams เป็นวัตถุที่มีพารามิเตอร์แบบสอบถาม: {name: novaline, age: 26}


หากคุณมีสิ่งนี้: http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer(เช่นไม่มี/หลังจาก#นั้น) จากนั้นสำหรับ react router v4 คุณควรใช้location.hashแทนlocation.search
codeVerine

10

ด้วยแพ็คเกจ stringquery:

import qs from "stringquery";

const obj = qs("?status=APPROVED&page=1limit=20");  
// > { limit: "10", page:"1", status:"APPROVED" }

ด้วยแพ็คเกจสตริงการสืบค้น:

import qs from "query-string";
const obj = qs.parse(this.props.location.search);
console.log(obj.param); // { limit: "10", page:"1", status:"APPROVED" } 

ไม่มีแพ็คเกจ:

const convertToObject = (url) => {
  const arr = url.slice(1).split(/&|=/); // remove the "?", "&" and "="
  let params = {};

  for(let i = 0; i < arr.length; i += 2){
    const key = arr[i], value = arr[i + 1];
    params[key] = value ; // build the object = { limit: "10", page:"1", status:"APPROVED" }
  }
  return params;
};


const uri = this.props.location.search; // "?status=APPROVED&page=1&limit=20"

const obj = convertToObject(uri);

console.log(obj); // { limit: "10", page:"1", status:"APPROVED" }


// obj.status
// obj.page
// obj.limit

หวังว่าจะช่วยได้ :)

ขอให้สนุกกับการเขียนโค้ด!


5
"react-router-dom": "^5.0.0",

คุณไม่จำเป็นต้องเพิ่มโมดูลเพิ่มเติมใด ๆ ในส่วนประกอบของคุณที่มีที่อยู่ URL เช่นนี้:

http: // localhost: 3000 / # /? authority '

คุณสามารถลองใช้รหัสง่ายๆต่อไปนี้:

    const search =this.props.location.search;
    const params = new URLSearchParams(search);
    const authority = params.get('authority'); //

4

หลังจากอ่านคำตอบอื่น ๆ (อันดับแรกโดย @ duncan-finney และจากนั้นโดย @Marrs) ฉันออกเดินทางเพื่อค้นหาบันทึกการเปลี่ยนแปลงที่อธิบายวิธีการตอบสนองเราเตอร์ 2.x สำนวนในการแก้ปัญหานี้ เอกสารเกี่ยวกับการใช้สถานที่ตั้ง (ที่คุณต้องการสำหรับการค้นหา) ในส่วนขัดแย้งจริงโดยรหัสจริง ดังนั้นหากคุณทำตามคำแนะนำของพวกเขาคุณจะได้รับคำเตือนที่โกรธเกรี้ยวเช่นนี้:

Warning: [react-router] `context.location` is deprecated, please use a route component's `props.location` instead.

ปรากฎว่าคุณไม่สามารถมีคุณสมบัติบริบทที่เรียกว่าตำแหน่งที่ใช้ประเภทตำแหน่งที่ตั้ง แต่คุณสามารถใช้คุณสมบัติบริบทที่เรียกว่า loc ที่ใช้ประเภทตำแหน่งที่ตั้ง ดังนั้นวิธีแก้ปัญหาคือการปรับเปลี่ยนเล็กน้อยในแหล่งที่มาดังนี้:

const RouteComponent = React.createClass({
    childContextTypes: {
        loc: PropTypes.location
    },

    getChildContext() {
        return { location: this.props.location }
    }
});

const ChildComponent = React.createClass({
    contextTypes: {
        loc: PropTypes.location
    },
    render() {
        console.log(this.context.loc);
        return(<div>this.context.loc.query</div>);
    }
});

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


1

วิธีง่ายๆ js:

queryStringParse = function(string) {
    let parsed = {}
    if(string != '') {
        string = string.substring(string.indexOf('?')+1)
        let p1 = string.split('&')
        p1.map(function(value) {
            let params = value.split('=')
            parsed[params[0]] = params[1]
        });
    }
    return parsed
}

และคุณสามารถโทรได้จากทุกที่โดยใช้:

var params = this.queryStringParse(this.props.location.search);

หวังว่านี่จะช่วยได้


0

คุณอาจได้รับข้อผิดพลาดต่อไปนี้ขณะสร้างบิลด์การผลิตที่ปรับให้เหมาะสมเมื่อใช้โมดูลสตริงแบบสอบถาม

ไม่สามารถย่อขนาดโค้ดจากไฟล์นี้: ./node_modules/query-string/index.js:8

เพื่อเอาชนะสิ่งนี้โปรดใช้โมดูลทางเลือกที่เรียกว่าstringqueryซึ่งทำกระบวนการเดียวกันได้ดีโดยไม่มีปัญหาใด ๆ ในขณะที่รันบิลด์

import querySearch from "stringquery";

var query = querySearch(this.props.location.search);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.