บางครั้ง
ฉันเคยเห็นคนห่อส่วนประกอบของพวกเขาwithRouterเมื่อพวกเขาส่งออก:
import { withRouter } from 'react-router-dom';
class Foo extends React.Component {
// ...
}
export default withRouter(Foo);
สิ่งนี้มีไว้เพื่ออะไรและควรใช้เมื่อใด
คำตอบ:
เมื่อคุณรวมส่วนประกอบของหน้าหลักไว้ในแอปของคุณองค์ประกอบนั้นมักจะรวมไว้ใน<Route>ส่วนประกอบเช่นนี้:
<Route path="/movies" component={MoviesIndex} />
โดยการทำเช่นนี้MoviesIndexองค์ประกอบที่มีการเข้าถึงเพื่อที่จะสามารถเปลี่ยนเส้นทางผู้ใช้ด้วยthis.props.historythis.props.history.push
ส่วนประกอบบางอย่าง (โดยทั่วไปคือส่วนประกอบส่วนหัว) จะปรากฏในทุกหน้าดังนั้นจึงไม่รวมอยู่ใน<Route>:
render() {
return (<Header />);
}
ซึ่งหมายความว่าส่วนหัวไม่สามารถเปลี่ยนเส้นทางผู้ใช้
เพื่อแก้ไขปัญหานี้องค์ประกอบส่วนหัวสามารถรวมอยู่ในwithRouterฟังก์ชันได้ทั้งเมื่อส่งออก:
export default withRouter(Header)
สิ่งนี้ให้การHeaderเข้าถึงคอมโพเนนต์this.props.historyซึ่งหมายความว่าตอนนี้ส่วนหัวสามารถเปลี่ยนเส้นทางผู้ใช้
historyหรือmatchไม่อยู่โดยปริยาย? กล่าวคือเหตุใดจึงwithRouterควรกล่าวถึงอย่างชัดเจน?
withRouterเป็นส่วนประกอบลำดับที่สูงกว่าซึ่งจะส่งผ่านเส้นทางที่ใกล้ที่สุดmatchปัจจุบันlocationและhistoryอุปกรณ์ประกอบฉากไปยังส่วนประกอบที่ถูกห่อเมื่อใดก็ตามที่แสดงผล เพียงแค่เชื่อมต่อส่วนประกอบกับเราเตอร์
ส่วนประกอบบางส่วนโดยเฉพาะส่วนประกอบที่ใช้ร่วมกันจะไม่สามารถเข้าถึงอุปกรณ์ประกอบฉากของเราเตอร์ดังกล่าวได้ ภายในส่วนประกอบห่อของคุณจะสามารถเข้าถึงlocationเสาและได้รับข้อมูลเพิ่มเติมเช่นlocation.pathnameหรือเปลี่ยนเส้นทางผู้ใช้ไปยัง URL this.props.history.pushที่แตกต่างกันโดยใช้
นี่คือตัวอย่างที่สมบูรณ์จากหน้า github ของพวกเขา:
import React from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router";
// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
};
render() {
const { match, location, history } = this.props;
return <div>You are now at {location.pathname}</div>;
}
}
// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation);
withRouterองค์ประกอบลำดับที่สูงขึ้นช่วยให้คุณสามารถเข้าถึงhistoryคุณสมบัติของวัตถุและการ<Route>จับคู่ที่ใกล้เคียงที่สุด withRouterจะผ่านการปรับปรุงmatch, locationและhistoryอุปกรณ์ประกอบฉากองค์ประกอบห่อเมื่อใดก็ตามที่จะแสดงผล
import React from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router";
// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
};
render() {
const { match, location, history } = this.props;
return <div>You are now at {location.pathname}</div>;
}
}
// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation);
withRouter เป็นส่วนประกอบลำดับที่สูงกว่าซึ่งจะส่งผ่านเส้นทางที่ใกล้ที่สุดเพื่อเข้าถึงคุณสมบัติบางอย่างเกี่ยวกับสถานที่ตั้งและจับคู่จากอุปกรณ์ประกอบฉากที่สามารถเข้าถึงได้ก็ต่อเมื่อให้องค์ประกอบคุณสมบัติที่อยู่ในส่วนประกอบ
<Route to="/app" component={helo} history ={history} />
และเดียวกันความเจริญรุ่งเรืองของการจับคู่และตำแหน่งเพื่อให้สามารถเปลี่ยนสถานที่และใช้ this.props.history.push ควรมีให้สำหรับคุณสมบัติแต่ละองค์ประกอบต้องให้ แต่เมื่อใช้ WithRouter จะสามารถเข้าถึงตำแหน่งและจับคู่ได้โดยไม่ต้องเพิ่มประวัติคุณสมบัติ สามารถเข้าถึงทิศทางโดยไม่ต้องเพิ่มประวัติทรัพย์สินจากแต่ละเส้นทาง
withRouterนอกจากนี้ยังช่วยให้การเข้าถึงและmatchมันคงจะดีถ้าคำตอบที่ได้รับการยอมรับที่กล่าวถึงว่าตั้งแต่เปลี่ยนเส้นทางผู้ใช้ไม่ได้เป็นกรณีที่ใช้เฉพาะสำหรับlocationwithRouterนี่เป็นตัวตนที่ดีอย่างอื่น