วิธีใดเป็นวิธีที่ดีที่สุดในการเปลี่ยนเส้นทางเพจโดยใช้ React Router


116

ฉันยังใหม่กับ React Router และเรียนรู้ว่ามีหลายวิธีในการเปลี่ยนเส้นทางเพจ:

  1. การใช้ browserHistory.push("/path")

    import { browserHistory } from 'react-router';
    //do something...
    browserHistory.push("/path");
    
  2. การใช้ this.context.router.push("/path")

    class Foo extends React.Component {
        constructor(props, context) {
            super(props, context);
            //do something...
        }
        redirect() {
            this.context.router.push("/path")
        }
    }
    
    Foo.contextTypes = {
        router: React.PropTypes.object
    }
    
  3. ใน React Router v4 มีthis.context.history.push("/path")และthis.props.history.push("/path"). รายละเอียด: จะพุชไปที่ History ใน React Router v4 ได้อย่างไร?

ฉันสับสนกับตัวเลือกเหล่านี้มากมีวิธีที่ดีที่สุดในการเปลี่ยนเส้นทางเพจหรือไม่?


คุณใช้ v4 ใช่หรือไม่
azium

1
ลิงก์ไปยังสแต็กอื่น ๆ ที่คุณโพสต์ค่อนข้างชัดเจนฉันขอแนะนำให้ใช้withRouter
azium

คำตอบ:


195

จริงๆแล้วมันขึ้นอยู่กับกรณีการใช้งานของคุณ

1) คุณต้องการปกป้องเส้นทางของคุณจากผู้ใช้ที่ไม่ได้รับอนุญาต

หากเป็นเช่นนั้นคุณสามารถใช้ส่วนประกอบที่เรียก<Redirect />และสามารถใช้ตรรกะต่อไปนี้:

import React from 'react'
import  { Redirect } from 'react-router-dom'

const ProtectedComponent = () => {
  if (authFails)
    return <Redirect to='/login'  />
  }
  return <div> My Protected Component </div>
}

โปรดทราบว่าหากคุณต้องการ<Redirect />ทำงานตามที่คุณคาดหวังคุณควรวางไว้ในวิธีการเรนเดอร์ของคอมโพเนนต์เพื่อให้ถือว่าเป็นองค์ประกอบ DOM ในที่สุดมิฉะนั้นจะไม่ทำงาน

2) คุณต้องการเปลี่ยนเส้นทางหลังจากดำเนินการบางอย่าง (สมมติว่าหลังจากสร้างรายการ)

ในกรณีนี้คุณสามารถใช้ประวัติ:

myFunction() {
  addSomeStuff(data).then(() => {
      this.props.history.push('/path')
    }).catch((error) => {
      console.log(error)
    })

หรือ

myFunction() {
  addSomeStuff()
  this.props.history.push('/path')
}

เพื่อที่จะได้เข้าถึงประวัติการคุณสามารถห่อส่วนประกอบของคุณด้วย HOC withRouterที่เรียกว่า เมื่อคุณรวมส่วนประกอบของคุณเข้าด้วยกันมันจะผ่านmatch locationและhistoryอุปกรณ์ประกอบฉาก สำหรับรายละเอียดเพิ่มเติมโปรดดูเอกสารอย่างเป็นทางการสำหรับ withRouter

หากองค์ประกอบของคุณเป็นลูกของ<Route />องค์ประกอบคือถ้ามันเป็นสิ่งที่ชอบ<Route path='/path' component={myComponent} />คุณจะได้ไม่ต้องห่อส่วนประกอบของคุณด้วยwithRouterเพราะ<Route />ที่ผ่านมาmatch, locationและhistoryเพื่อเด็ก

3) เปลี่ยนเส้นทางหลังจากคลิกองค์ประกอบบางส่วน

มีสองตัวเลือกที่นี่ คุณสามารถใช้history.push()โดยส่งต่อไปยังonClickเหตุการณ์:

<div onClick={this.props.history.push('/path')}> some stuff </div>

หรือคุณสามารถใช้<Link />ส่วนประกอบ:

 <Link to='/path' > some stuff </Link>

ฉันคิดว่าหลักการง่ายๆในกรณีนี้คือการพยายามใช้<Link />ก่อนฉันคิดว่าโดยเฉพาะอย่างยิ่งเนื่องจากประสิทธิภาพ


มันใช้งานได้สำหรับฉัน `this.props.history.push (" / "); React-router - v4.2ขอบคุณ @Cagri
MD Ashik

stackoverflow.com/questions/60579292/…คุณช่วยดู qs นี้ได้ไหม
a125

ในตัวเลือกสุดท้ายเนื่องจากคอมโพเนนต์มีhistoryอุปกรณ์ประกอบฉากที่สามารถทำได้this.props.history.push('/path')หมายความว่าส่วนประกอบนั้นเป็นลูกของ<Route/>หรือมีwithRouterwrapper ในการส่งออกถูกต้อง?
Andre

ดังนั้นจึงเป็นไปได้ที่จะกำหนดเส้นทางไปยังส่วนประกอบอื่นโดยไม่ต้องระบุ<Route path='/path' component={Comp}/>ฉันเดาว่าธรรมดาrender() { return <Comp/>}ในเงื่อนไข?
Andre

@ Andre ใช่ถูกต้องสำหรับการใช้งานthis.props.historyอย่างไรก็ตามฉันไม่แน่ใจว่าคำถามที่สองของคุณถูกต้องหรือไม่? คุณหมายถึงอะไรกันแน่route to another component?
Cagri Yardimci

11

ตอนนี้ด้วย react-router v15.1และเป็นต้นไปเราสามารถuseHistoryขอได้นี่เป็นวิธีที่ง่ายและชัดเจนมาก นี่คือตัวอย่างง่ายๆจากบล็อกต้นทาง

import { useHistory } from "react-router-dom";

function BackButton({ children }) {
  let history = useHistory()
  return (
    <button type="button" onClick={() => history.goBack()}>
      {children}
    </button>
  )
}

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

เรียนรู้เพิ่มเติมที่นี่https://reacttraining.com/blog/react-router-v5-1/#usehistory



1

วิธีที่ง่ายที่สุดวิธีหนึ่ง: ใช้ Link ดังนี้:

import { Link } from 'react-router-dom';

<Link to={`your-path`} activeClassName="current">{your-link-name}</Link>

หากเราต้องการครอบคลุมส่วน div ทั้งหมดเป็นลิงก์:

 <div>
     <Card as={Link} to={'path-name'}>
         .... 
           card content here
         ....
     </Card>
 </div>


0

นอกจากนี้คุณยังสามารถRedirectภายในRouteดังนี้ นี่คือการจัดการเส้นทางที่ไม่ถูกต้อง

<Route path='*' render={() => 
     (
       <Redirect to="/error"/>
     )
}/>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.