HashRouter กับ BrowserRouter


121

ฉันยังใหม่กับการเขียนโปรแกรมซึ่งทำให้ฉันเข้าใจสิ่งต่าง ๆ ได้ยากเล็กน้อยหากฉันอ่านเอกสารอย่างเป็นทางการ

ฉันอ่านเกี่ยวกับReact Router 4 จากที่นี่

ในบทความนี้ผู้เขียนกำลังพูดถึง<HashRouter>และ<BrowserRouter>

นี่คือสิ่งที่เขากล่าวถึง

โดยทั่วไปแล้วHashRouterจะใช้แฮชใน URL เพื่อแสดงผลคอมโพเนนต์ เนื่องจากฉันกำลังสร้างเว็บไซต์หน้าเดียวแบบคงที่ฉันจึงต้องใช้สิ่งนี้

BrowserRouterใช้ HTML5 history API เพื่อแสดงผลคอมโพเนนต์ ประวัติสามารถแก้ไขได้ผ่าน pushState และ replaceState ข้อมูลเพิ่มเติมสามารถดูได้ที่นี่

ตอนนี้ฉันไม่ได้รับความสำคัญและกรณีการใช้งานสำหรับทั้งสองเช่นเขาหมายถึงอะไรเมื่อเขาบอกว่าประวัติสามารถแก้ไขได้ผ่าน pushState และ replaceStateและใช้แฮชใน URL เพื่อแสดงองค์ประกอบ

แม้ว่าคำอธิบายแรกของ BrowserRouter จะคลุมเครือสำหรับฉัน แต่คำอธิบายที่สองเกี่ยวกับ HashRouter ก็ไม่สมเหตุสมผลเช่นทำไมบางคนถึงใช้ Hash (#) ใน url เพื่อแสดงผลส่วนประกอบ



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

คำตอบ:


133

BrowserRouter

ใช้API ประวัติกล่าวคือไม่สามารถใช้ได้กับเบราว์เซอร์รุ่นเก่า (IE 9 และต่ำกว่าและรุ่นเดียวกัน) แอปพลิเคชัน React ฝั่งไคลเอ็นต์สามารถรักษาเส้นทางที่สะอาดเช่นexample.com/react/routeแต่ต้องได้รับการสนับสนุนจากเว็บเซิร์ฟเวอร์ โดยปกติหมายความว่าควรกำหนดค่าเว็บเซิร์ฟเวอร์สำหรับแอ็พพลิเคชันแบบหน้าเดียวกล่าวindex.htmlคือให้บริการสำหรับ/ react / route path หรือเส้นทางอื่น ๆ บนฝั่งเซิร์ฟเวอร์ ในฝั่งไคลเอ็นต์window.location.pathnameจะแยกวิเคราะห์โดย React router ตอบสนองเราเตอร์ทำให้องค์ประกอบที่มีการกำหนดค่าการแสดงผลสำหรับ/ ตอบสนอง / เส้นทาง

นอกจากนี้การตั้งค่าอาจเกี่ยวข้องกับการแสดงผลฝั่งเซิร์ฟเวอร์index.htmlอาจมีส่วนประกอบที่แสดงผลหรือข้อมูลที่เฉพาะเจาะจงสำหรับเส้นทางปัจจุบัน

HashRouter

ใช้แฮช URL ทำให้ไม่มีข้อ จำกัด สำหรับเบราว์เซอร์หรือเว็บเซิร์ฟเวอร์ที่รองรับ การกำหนดเส้นทางฝั่งเซิร์ฟเวอร์ไม่ขึ้นอยู่กับการกำหนดเส้นทางฝั่งไคลเอ็นต์

โปรแกรมเดียวหน้าย้อนกลับกันได้สามารถใช้มันเป็นexample.com/#/react/route ไม่สามารถสำรองการตั้งค่าโดยการแสดงผลฝั่งเซิร์ฟเวอร์ได้เนื่องจากเป็น/เส้นทางที่ให้บริการบนฝั่งเซิร์ฟเวอร์แฮช URL # / react / routeจากฝั่งเซิร์ฟเวอร์ไม่สามารถอ่านได้ ในฝั่งไคลเอ็นต์window.location.hashจะแยกวิเคราะห์โดย React router ตอบสนองเราเตอร์ทำให้องค์ประกอบที่มีการกำหนดค่าการแสดงผลสำหรับ/ ตอบสนอง / เส้นทางคล้าย ๆ BrowserRouterกับ

ที่สำคัญที่สุดคือHashRouterกรณีการใช้งานไม่ได้ จำกัด เฉพาะสปา เว็บไซต์อาจมีมรดกหรือเครื่องมือค้นหาง่ายฝั่งเซิร์ฟเวอร์เส้นทางในขณะที่ตอบสนองการประยุกต์ใช้อาจจะเป็นเครื่องมือที่จะรักษาสถานะของมันใน URL เหมือนexample.com/server/side/route#/react/route บางเพจที่มีแอ็พพลิเคชัน React จะถูกแสดงบนฝั่งเซิร์ฟเวอร์สำหรับ/ server / side / routeจากนั้นบนฝั่งไคลเอ็นต์ React router จะแสดงส่วนประกอบที่ได้รับการกำหนดค่าให้แสดงผลสำหรับ/ react / routeซึ่งคล้ายกับสถานการณ์ก่อนหน้า


2
อีกประเด็นหนึ่ง - หากคุณต้องการการนำทางบนหน้า (ซึ่งก็คือตำแหน่งโดยทั่วไปแฮชได้รับการออกแบบมาสำหรับและควรจะทำงานนอกกรอบ) มันค่อนข้างยากที่จะนำไปใช้
WhiteKnight

2
@iRohitBhatia BrowserHistory ยังให้คุณทำการเรนเดอร์ฝั่งเซิร์ฟเวอร์เนื่องจากเซิร์ฟเวอร์สามารถเข้าถึง URL แบบเต็มได้ เซิร์ฟเวอร์ไม่สามารถเข้าถึงเส้นทางที่อยู่เบื้องหลังไฟล์#.
Sébastien Loix

31

ด้านเซิร์ฟเวอร์: HashRouter ใช้สัญลักษณ์แฮชใน URL ซึ่งมีผลทำให้เนื้อหาเส้นทาง URL ที่ตามมาทั้งหมดถูกละเว้นในคำขอของเซิร์ฟเวอร์ (เช่นคุณส่ง "www.mywebsite.com/#/person/john" เซิร์ฟเวอร์จะได้รับ "www .mywebsite.com "ดังนั้นเซิร์ฟเวอร์จะส่งคืนการตอบกลับ URL ก่อน # จากนั้นเส้นทาง # จะถูกจัดการโดยแยกวิเคราะห์โดยแอปพลิเคชันการตอบกลับฝั่งไคลเอ็นต์ของคุณ

ฝั่งลูกค้า: BrowserRouter จะไม่ใส่สัญลักษณ์ # ต่อท้าย URL ของคุณอย่างไรก็ตามจะสร้างปัญหาเมื่อคุณพยายามเชื่อมโยงไปยังเพจหรือโหลดเพจซ้ำ หากเส้นทางที่ชัดเจนมีอยู่ในแอปตอบสนองไคลเอนต์ของคุณ แต่ไม่มีบนเซิร์ฟเวอร์ของคุณการโหลดซ้ำและการเชื่อมโยง (สิ่งใดก็ตามที่กระทบเซิร์ฟเวอร์โดยตรง) จะส่งคืนข้อผิดพลาด 404


7

ทั้งสองBrowserRouterและHashRouterส่วนประกอบถูกนำมาใช้ใน React Router เวอร์ชัน 4 เป็นคลาสย่อยของRouterคลาส เพียงแค่BrowserRouterซิงค์ UI กับ URL ปัจจุบันในเบราว์เซอร์ของคุณซึ่งทำได้โดยใช้ HTML-5 History API ในทางกลับกันHashRouterใช้ส่วนแฮชของ URL ของคุณเพื่อซิงค์


7

"กรณีการใช้งาน"

HashRouter:เมื่อเรามีแอปพลิเคชันฝั่งไคลเอนต์ขนาดเล็กซึ่งไม่จำเป็นต้องใช้แบ็กเอนด์เราสามารถใช้ได้HashRouterเพราะเมื่อเราใช้แฮชในเบราว์เซอร์ URL / แถบตำแหน่งจะไม่ทำการร้องขอเซิร์ฟเวอร์

BrowserRouter:<BrowserRouter>เมื่อเรามีการใช้งานการผลิตพร้อมขนาดใหญ่ที่ทำหน้าที่แบ็กเอนด์ก็จะแนะนำให้ใช้

อ้างอิงจากหนังสือ: Learning React: Functional Web Development with React และ Redux โดย Alex Banks, Eve Porcello


22
Imho "HashRouter" กับ "BrowserRouter" ไม่มีส่วนเกี่ยวข้องกับแอปพลิเคชัน "ขนาดเล็ก" กับ "ขนาดใหญ่ที่พร้อมสำหรับการผลิต ไม่มีปัญหาด้านขีด จำกัด หรือประสิทธิภาพการใช้งาน HashRouter ในแอปพลิเคชันที่พร้อมใช้งานจริงขนาดใหญ่ ทุกอย่างเกี่ยวกับกรณีการใช้งานข้อกำหนดและสถาปัตยกรรมที่ได้รับโดยเฉพาะ แอปพลิเคชันการผลิตแบบไม่ใช้เซิร์ฟเวอร์เป็นของจริง
Pawel Sas

5

การรีเฟรชเพจทำให้เบราว์เซอร์ส่งคำขอ GET ไปยังเซิร์ฟเวอร์โดยใช้เส้นทางปัจจุบัน # ถูกใช้เพื่อป้องกันไม่ให้เราส่งคำขอ GET นั้น เราใช้ BrowserRouter เนื่องจากเราต้องการให้ส่งคำขอ GET ไปยังเซิร์ฟเวอร์ ในการแสดงเราเตอร์บนเซิร์ฟเวอร์เราต้องการตำแหน่ง - เราต้องการเส้นทาง เส้นทางนี้จะใช้บนเซิร์ฟเวอร์เพื่อบอกเราเตอร์ว่าจะแสดงผลอะไร BrowserRouter ใช้เมื่อคุณต้องการแสดงเส้นทางแบบ isomorphically


1

อีกหนึ่งกรณีการใช้งานที่ฉันต้องการเพิ่ม ในขณะที่ใช้ BrowserRouter หรือ Router มันจะทำงานได้ดีบนเซิร์ฟเวอร์โหนดของเรา เนื่องจากเข้าใจการกำหนดเส้นทางไคลเอ็นต์ (กำหนดค่าล่วงหน้า)

แต่ในขณะที่เราปรับใช้แอป build React บนเซิร์ฟเวอร์ Apache (พูดแค่ PHP บน GoDaddy) การกำหนดเส้นทางจะไม่ทำงานตามที่คาดไว้ มันจะเข้าสู่ 404 ซึ่งเราต้องกำหนดค่าไฟล์. htaccess หลังจากนั้นสำหรับฉันแต่ละคลิก / url การส่งคำขอไปยังเซิร์ฟเวอร์

ในกรณีนี้เราควรใช้ HASH Routing (#) ดีกว่า # เราใช้สิ่งนี้ในหน้า html ของเราสำหรับการสำรวจในเนื้อหา HTML และจะไม่นำไปสู่การร้องขอของเซิร์ฟเวอร์

ในสถานการณ์ข้างต้นเราสามารถใช้ HashRouting นั่นคือ url ทั้งหมดที่ปรากฏหลัง # เราสามารถกำหนดให้กฎการกำหนดเส้นทางของเราทำงานเป็น SPA ได้


0

โดยทั่วไปถ้าใครใช้ BrowserRouter เราสามารถใช้ url เช่น "soAndSoReactPage /: id"

เช่น:

with a Route <Route path="soAndSoReactPage/:id"><soAndSoReactComponent/></Route>

ตอนนี้ในองค์ประกอบการตอบสนอง "soAndSoReactComponent" นั้น "id" สามารถแยกโดยใช้ useParams และทำให้คุณสามารถแสดงหน้า "soAndSoReactComponent" ได้ตามรหัส

สิ่งนี้ไม่สามารถทำได้ด้วย HashedRouter


0

อ้างอิงจากhttps://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/HashRouter.mdผู้เขียนไม่แนะนำ HashRouter สำหรับสถานการณ์ทั่วไป:

เนื่องจากเทคนิคนี้มีไว้เพื่อรองรับเบราว์เซอร์เดิมเท่านั้นเราขอแนะนำให้คุณกำหนดค่าเซิร์ฟเวอร์ของคุณให้ใช้งานได้แทน

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