reactjs - tutorial - react-router-dom




انتقل برمجياً باستخدام جهاز توجيه الرد (20)

رد فعل جهاز التوجيه V4

TL: الدكتور.

let Authentication = React.createClass({
  contextTypes: {
    router: React.PropTypes.func
  },
  handleClick(e) {
    e.preventDefault();
    this.context.router.transitionTo('/');
  },
  render(){
    return (<div onClick={this.handleClick}>Click me!</div>);
  }
});

الإجابة البسيطة setState() هي أنك تحتاج إلى استخدام <Redirect to={URL} push={boolean} /> بالاقتران مع setState()

push: منطقي - عندما يكون true ، ستؤدي إعادة التوجيه إلى إدخال إدخال جديد على السجل بدلاً من استبدال الإدخال الحالي.

import { withRouter } from 'react-router';

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

// Export the decorated class
export default withRouter(Example);

المثال الكامل here . اقرأ المزيد here .

ملاحظة. يستخدم المثال مُهيئات خاصية ES7 + لتهيئة الحالة. انظر here أيضًا ، إذا كنت مهتمًا.

باستخدام react-router يمكنني استخدام عنصر Link لإنشاء ارتباطات يتم التعامل معها أصلاً بواسطة جهاز توجيه التفاعل.

أرى داخليًا أنه يستدعي this.context.transitionTo(...) .

أريد أن أفعل التنقل ، ولكن ليس من رابط ، من اختيار القائمة المنسدلة على سبيل المثال. كيف يمكنني القيام بذلك في الكود؟ ما هو this.context .

رأيت مزيج Navigation ، لكن هل يمكنني القيام بذلك دون خلطات؟


لرد فعل راوتر v4 +

على افتراض أنك لن تحتاج إلى التنقل خلال العرض الأولي نفسه (والذي يمكنك من خلاله استخدام <Redirect> المكون) ، هذا ما نقوم به في تطبيقنا.

حدد مسارًا فارغًا يُرجع خالية ، مما سيتيح لك الوصول إلى كائن السجل. تحتاج إلى القيام بذلك في المستوى الأعلى حيث Router يتم تعريف الخاص بك .

الآن يمكنك أن تفعل كل الأشياء التي يمكن القيام به على history مثل history.push() ، history.replace() ، history.go(-1) الخ!

 import React from 'react'; import { HashRouter, Route } from 'react-router-dom'; let routeHistory = null; export function navigateTo(path) { if(routeHistory !== null) { routeHistory.push(path); } } export default function App(props) { return ( <HashRouter hashType="noslash"> <Route render={({ history }) => { routeHistory = history; return null; }} /> {/* Rest of the App */} </HashRouter> ); } 

React-Router 5.1.0+ إجابة (باستخدام الخطافات و React> 16.8)

يمكنك استخدام useHistory الجديد على المكونات الوظيفية والتنقل برمجياً:

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

React-Router 4.0.0+ إجابة

في 4.0 وما فوق ، استخدم السجل كدعامة للمكون الخاص بك.

import { withRouter } from 'react-router';

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

// Export the decorated class
var DecoratedExample = withRouter(Example);

// PropTypes
Example.propTypes = {
  router: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired
  }).isRequired
};

ملاحظة: this.props.history غير موجود في حالة عدم تقديم المكون الخاص بك بواسطة <Route> . يجب عليك استخدام <Route path="..." component={YourComponent}/> للحصول على this.props.history في YourComponent

React-Router 3.0.0+ إجابة

في الإصدار 3.0 والإصدارات الأحدث ، استخدم جهاز التوجيه كدعم للمكون.

var Example = React.createClass({
  mixins: [ History ],
  navigateToHelpPage () {
    this.history.pushState(null, `/help`);
  }
})

React-Router 2.4.0+ إجابة

في 2.4 وما فوق ، استخدم مكونًا ذو ترتيب أعلى للحصول على جهاز التوجيه كدعم للمكون.

import React from 'react';
import {Navigation} from 'react-router';

let Authentication = React.createClass({
  mixins: [Navigation],

  handleClick(e) {
    e.preventDefault();

    this.transitionTo('/');
  },

  render(){
    return (<div onClick={this.handleClick}>Click me!</div>);
  }
});

React-Router 2.0.0+ إجابة

هذا الإصدار متوافق مع الإصدارات السابقة 1.x لذلك لا داعٍ لقيام دليل الترقية. مجرد الذهاب من خلال الأمثلة يجب أن تكون جيدة بما فيه الكفاية.

ومع ذلك ، إذا كنت ترغب في التبديل إلى النمط الجديد ، فهناك وحدة مستعرض التاريخ داخل جهاز التوجيه التي يمكنك الوصول إليها

import { browserHistory } from 'react-router'

يمكنك الآن الوصول إلى سجل المتصفح الخاص بك ، بحيث يمكنك القيام بأشياء مثل الضغط أو الاستبدال أو ما إلى ذلك ... مثل:

browserHistory.push('/some/path')

مزيد من القراءة: Histories Navigation

React-Router 1.xx الإجابة

لن أخوض في تحديث التفاصيل. يمكنك أن تقرأ عن ذلك في دليل الترقية

التغيير الرئيسي حول السؤال هنا هو التغيير من مزيج التنقل إلى السجل. الآن تستخدم محفوظات المستعرض API لتغيير المسار لذلك سنستخدم pushState() من الآن فصاعدًا.

وإليك مثال باستخدام Mixin:

import React from 'react';

export default class Authentication extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(e) {
    e.preventDefault();

    this.context.router.transitionTo('/');
  }

  render(){
    return (<div onClick={this.handleClick}>Click me!</div>);
  }
}

Authentication.contextTypes = {
  router: React.PropTypes.func.isRequired
};

لاحظ أن هذا rackt/history يأتي من مشروع rackt/history . ليس من رد فعل راوتر نفسه.

إذا كنت لا ترغب في استخدام Mixin لسبب ما (ربما بسبب فئة ES6) ، يمكنك الوصول إلى السجل الذي تحصل عليه من جهاز التوجيه من this.props.history . سيكون متاحًا فقط للمكونات التي يقدمها جهاز التوجيه الخاص بك. لذلك ، إذا كنت ترغب في استخدامه في أي مكونات فرعية ، فيجب أن يتم نقله props عبر props .

يمكنك قراءة المزيد حول الإصدار الجديد في وثائق 1.0.x الخاصة بهم

فيما يلي صفحة مساعدة خاصة حول التنقل خارج المكون الخاص بك

وتوصي الاستيلاء على history = createHistory() مرجعي history = createHistory() واستدعاء replaceState على ذلك.

React-Router 0.13.x إجابة

واجهت نفس المشكلة ولم أتمكن من العثور إلا على حل باستخدام مزيج التنقل الذي يأتي مع جهاز توجيه التفاعل.

إليك كيف فعلت ذلك

import { goBack } from 'react-router-redux'

export const onBackPress = () => (dispatch) => dispatch(goBack())

كنت قادراً على الاتصال transitionTo() دون الحاجة إلى الوصول إلى .context

أو يمكنك تجربة class ES6 الفاخرة

<button
  disabled={submitting}
  className="cancel_button"
  onClick={(e) => {
    e.preventDefault()
    this.props.onBackPress()
  }}
>
  CANCEL
</button>

الرد-راوتر-مسترجع

ملاحظة: إذا كنت تستخدم Redux ، فهناك مشروع آخر يسمى React-Router-Redux يمنحك ارتباطات redux لـ ReactRouter ، باستخدام الطريقة نفسها التي يتبعها React React-Redux ما

يحتوي React-Router-Redux على عدد قليل من الأساليب المتاحة التي تسمح بالتنقل البسيط من منشئي الحركة الداخلية. يمكن أن تكون هذه مفيدة بشكل خاص للأشخاص الذين لديهم بنية حالية في React Native ، ويرغبون في استخدام نفس الأنماط في React Web مع الحد الأدنى من الحمل المتداول.

استكشف الطرق التالية:

  • push(location)
  • replace(location)
  • go(number)
  • goBack()
  • goForward()

فيما يلي مثال للاستخدام ، مع Redux-Thunk :

./actioncreators.js

import { browserHistory } from 'react-router';
browserHistory.push('/some/path');

./viewcomponent.js

this.props.history.push('/some/path');

تحذير: تغطي هذه الإجابة فقط إصدارات ReactRouter قبل 1.0

سوف أقوم بتحديث هذه الإجابة بحالات استخدام 1.0.0-rc1 بعد!

يمكنك القيام بذلك دون خلطات أيضا.

withRouter(Example);
export { Example };

إن مسكتك مع السياقات هي أنه لا يمكن الوصول إليها إلا إذا قمت بتعريف سياق contextTypes على الفصل الدراسي.

أما بالنسبة للسياق ، فهو كائن ، مثل الدعائم ، ينتقل من الوالدين إلى الطفل ، لكنه ينتقل ضمنيًا ، دون الحاجة إلى إعادة تعريف الدعائم في كل مرة. انظر https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html


رد فعل راوتر v2

بالنسبة إلى أحدث إصدار ( v2.0.0-rc5 ) ، تتمثل طريقة التنقل الموصى بها في الضغط مباشرة على السجل المنفرد. يمكنك أن ترى ذلك قيد التنفيذ في مستند التنقل خارج المكونات .

مقتطفات ذات صلة:

import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));

إذا كنت تستخدم واجهة برمجة تطبيقات رد فعل الموجه الأحدث ، فأنت بحاجة إلى استخدام history من this.props عندما يكون داخل المكونات:

import React from 'react';

export default class MyComponent extends React.Component {
  navigateToPage = () => {
    this.context.router.push('/my-route')
  };

  render() {
    return (
      <button onClick={this.navigateToPage}>Go!</button>
    );
  }
}

MyComponent.contextTypes = {
  router: React.PropTypes.object.isRequired
}

كما يوفر pushState ولكن يتم إهمال كل تحذيرات مسجلة.

في حالة استخدام react-router-redux ، فإنه يوفر وظيفة push يمكنك إرسالها على النحو التالي:

import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()

ومع ذلك ، يمكن استخدام هذا فقط لتغيير عنوان URL ، وليس للتنقل فعليًا إلى الصفحة.


رد فعل راوتر v5.1.0 مع السنانير

يوجد useHistory جديد في useHistory Router> 5.1.0 إذا كنت تستخدم React> 16.8.0 ومكونات وظيفية.

import { withRouter } from 'react-router-dom'
// this also works with react-router-native

const Button = withRouter(({ history }) => (
  <button
    type='button'
    onClick={() => { history.push('/new-location') }}
  >
    Click Me!
  </button>
))

رد فعل راوتر v4

مع v4 من React Router ، هناك ثلاثة طرق يمكنك اتباعها لتوجيه البرامج ضمن المكونات.

  1. استخدم withRouter ذو الترتيب العالي withRouter .
  2. استخدام التكوين وتقديم <Route>
  3. استخدم context .

React Router عبارة عن غلاف حول مكتبة history . يعالج history التفاعل مع window.history للمتصفح من خلال متصفحه وتاريخ التجزئة. يوفر أيضًا محفوظات ذاكرة مفيدة للبيئات التي ليس لها تاريخ عالمي. هذا مفيد بشكل خاص في تطوير تطبيقات الأجهزة المحمولة ( react-native ) واختبار الوحدة باستخدام Node.

مثيل history له طريقتان للتنقل: push replace . إذا كنت تفكر في history كصفيف من المواقع التي تمت زيارتها ، push ميزة " push " موقعًا جديدًا إلى المصفوفة replace الموقع محل الموقع الحالي في المصفوفة محل الموقع الحالي. عادةً ما تريد استخدام طريقة push عند التنقل.

في الإصدارات السابقة من React Router ، كان عليك إنشاء مثيل history الخاص بك ، ولكن في <BrowserRouter> ، <HashRouter> و <MemoryRouter> و <MemoryRouter> بإنشاء مستعرض ، وتجزئة ، ومثيلات ذاكرة لك. يتيح React Router توفير خصائص وطريقة مثيل history المرتبطة بجهاز التوجيه من خلال السياق ، أسفل كائن router .

1. استخدم withRouter ذو الترتيب العالي withRouter

سيقوم withRouter ذو الترتيب العالي withRouter بحقن كائن history كدعامة للمكون. يتيح لك ذلك الوصول إلى طرق push replace دون الحاجة إلى التعامل مع context .

import { Route } from 'react-router-dom'

const Button = () => (
  <Route render={({ history}) => (
    <button
      type='button'
      onClick={() => { history.push('/new-location') }}
    >
      Click Me!
    </button>
  )} />
)

2. استخدام التكوين وتقديم <Route>

المكون <Route> ليس فقط لمطابقة المواقع. يمكنك تقديم مسار بدون مسار وسوف يتطابق دائمًا مع الموقع الحالي . يمرر المكون <Route> نفس الدعائم كما هو withRouter مع withRouter ، لذلك ستتمكن من الوصول إلى أساليب history خلال prop history .

const Button = (props, context) => (
  <button
    type='button'
    onClick={() => {
      // context.history.push === history.push
      context.history.push('/new-location')
    }}
  >
    Click Me!
  </button>
)

// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired
  })
}

3. استخدم السياق *

ولكن ربما لا ينبغي لك

الخيار الأخير هو الخيار الذي يجب عليك استخدامه فقط إذا كنت تشعر بالراحة في العمل مع نموذج context React. على الرغم من أن السياق يعد خيارًا ، إلا أنه يجب التأكيد على أن السياق عبارة عن واجهة برمجة تطبيقات غير مستقرة وأن React له قسم لماذا لا يستخدم السياق في وثائقه. لذلك استخدام على مسؤوليتك الخاصة!

class Example extends React.Component {
   // use `this.props.history.push('/some/path')` here
};

1 و 2 هما أبسط الخيارات للتنفيذ ، لذلك بالنسبة لمعظم حالات الاستخدام ، فهي أفضل رهاناتك.


إذا حدث ذلك لإقران RR4 w / redux من خلال react-router-redux الفعل- react-router-redux ، فاستخدم منشئي إجراء التوجيه react-router-redux خيارًا أيضًا.

Header.contextTypes = {
  router: PropTypes.object.isRequired
}
export default Header;

إذا كنت تستخدم redux thunk / saga لإدارة التدفق غير المتزامن ، فإن استيراد منشئي الإجراءات أعلاه في إجراءات redux وربط الخطاف لتفاعل المكونات باستخدام mapDispatchToProps قد يكون أفضل.


ببساطة مجرد استخدام this.props.history.push('/where/to/go');


رد فعل راوتر V4

إذا كنت تستخدم الإصدار 4 ، فيمكنك استخدام مكتبتي (قابس Shameless) حيث يمكنك ببساطة إرسال إجراء وكل شيء يعمل فقط!

import history from './history' 

history.push('/test') // this should change the url and re-render Test component

trippler


كانت الإجابة الصحيحة بالنسبة لي في وقت كتابة هذا التقرير

import PropTypes from 'prop-types';

لكنك تحتاج إلى إضافة PropTypes إلى المكون الخاص بك

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

// create functional component Post
export default Post = () => (
    <div className="component post">

        <button className="button delete-post" onClick={() => {
            // ... delete post
            // then redirect, without page reload, by triggering a hidden Link
            document.querySelector('.trigger.go-home').click();
        }}>Delete Post</button>

        <Link to="/" className="trigger go-home hidden"></Link>

    </div>
);

لا تنسى أن تستورد PropTypes

import React from 'react';
import { HashRouter, Route } from 'react-router-dom';

let routeHistory = null;

export function navigateTo(path) {
  if(routeHistory !== null) {
    routeHistory.push(path);
  }
}

export default function App(props) {
  return (
    <HashRouter hashType="noslash">
      <Route
        render={({ history }) => {
          routeHistory = history;
          return null;
        }}
      />
      {/* Rest of the App */}
    </HashRouter>
  );
}

هذا عملت لي ، لا حاجة إلى واردات خاصة:

 <input type="button" name="back" id="back" class="btn btn-primary" value="Back" onClick={() => { this.props.history.goBack() }} /> 

يمكنك أيضًا استخدام useHistory الخطاف في مكون عديم الحالة. مثال من المستندات.

 import { useHistory } from "react-router" function HomeButton() { const history = useHistory() return ( <button type="button" onClick={() => history.push("/home")}> Go home </button> ) } 

ملاحظة: تم إضافة السنانير في [email protected] وتتطلب [email protected]>=16.8


إليك كيفية القيام بذلك باستخدام ES6 react-router v2.0.0 مع ES6 . react-router ابتعد عن الخلطات.

import React, { Component } from 'react';
import history from './history';

class BasicComponent extends Component {

    goToIndex(e){
        e.preventDefault();
        history.push('/');
    }

    render(){
        return <a href="#" onClick={this.goToIndex}>Previous</a>;
    }
}

بالنسبة لمكونات ES6 + React ، كان الحل التالي يعمل بالنسبة لي.

تابعت Felippe skinner ، لكنني أضفت حلاً نهائيًا لمساعدة المبتدئين مثلي.

فيما يلي الإصدارات التي استخدمتها:

"react-router": "^ 2.7.0"

"رد فعل": "^ 15.3.1"

يوجد أدناه مكون التفاعل الخاص بي حيث استخدمت التنقل البرنامجي باستخدام جهاز توجيه التفاعل:

import Router from 'react-router/BrowserRouter';
import { History } from 'react-history/BrowserHistory';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();

interface MatchWithPropsInterface {
  component: typeof React.Component,
  router: Router,
  history: History,
  exactly?: any,
  pattern: string
}

class MatchWithProps extends React.Component<MatchWithPropsInterface,any> {
  render() {
    return(
      <Match {...this.props} render={(matchProps) => (
             React.createElement(this.props.component, this.props)

        )}
       />
    )
  }
}

ReactDOM.render(
    <Router>
      {({ router }) => (
        <div>
          <MatchWithProps exactly pattern="/" component={LoginPage} router={router} history={history} />
          <MatchWithProps pattern="/login" component={LoginPage} router={router} history={history} />
          <MatchWithProps pattern="/homepage" component={HomePage} router={router} history={history} />
          <Miss component={NotFoundView} />
        </div>
      )}
    </Router>,

   document.getElementById('app')
);

يوجد أدناه التكوين لجهاز التوجيه الخاص بي:

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

class Home extends Component {

    componentDidMount() {
        this.props.history.push('/redirect-to');
    }
}

export default withRouter(Home);

حاولت ما لا يقل عن 10 طرق للقيام بذلك قبل أن يعمل شيء صحيح!

كانت إجابةFelipe Skinner لـ withRouter غامرة قليلاً بالنسبة لي ، ولم أكن متأكدًا من withRouter في withRouter جديدة لـ "ExportedWithRouter".

فيما يلي أبسط وأنظف طريقة للقيام بذلك ، React-Router الحالي حوالي 3.0.0 و ES6:

React-Router 3.xx مع ES6:

   this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'

أو ، إذا لم تكن الفئة الافتراضية الخاصة بك ، فقم بالتصدير مثل:

//using ES6
import React from 'react';

class App extends React.Component {

  constructor(props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick(e) {
    e.preventDefault()
    /* Look at here, you can add it here */
    this.props.history.push('/redirected');
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick}>
          Redirect!!!
        </button>
      </div>
    )
  }
}

export default App;

لاحظ أنه في الإصدار router.push ، يستخدم المكون <Link> نفسه router.push ، بحيث يمكنك تمريره لأي شيء يمكنك تمريره <Link to= العلامة <Link to= ، مثل:

import React from 'react';

class loginComp extends React.Component {
   constructor( context) {
    super(context);
    this.state = {
      uname: '',
      pwd: ''
    };
  }

  redirectToMainPage(){
        this.context.router.replace('/home');
  }

  render(){
    return <div>
           // skipping html code 
             <button onClick={this.redirectToMainPage.bind(this)}>Redirect</button>
    </div>;
  }
};

 loginComp.contextTypes = {
    router: React.PropTypes.object.isRequired
 }

 module.exports = loginComp;

في رد فعل جهاز التوجيه V4. أتبع هذا طريقين لتوجيه برمجيًا.

import React from 'react';

class MyComponent extends React.Component {

    constructor(props) {
        super(props);
        this.backPressed = this.backPressed.bind(this);
    }

    backPressed() {
        this.context.router.push('/back-location');
    }

    ...
}

MyComponent.contextTypes = {
    router: React.PropTypes.object.isRequired
};

export default MyComponent;

الرقم اثنان

يستبدل الإدخال الحالي في مكدس المحفوظات

للحصول على التاريخ في الدعائم قد تضطر إلى التفاف مكون الخاص بك مع

withRouter


لاستخدام withRouter مع مكون قائم على الفصل ، جرب شيئًا كهذا أدناه. لا تنسَ تغيير عبارة التصدير لاستخدامها مع withRouter :

import { withRouter } from 'react-router-dom'

import { MemoryRouter, BrowserRouter } from 'react-router';

const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;

<Router location="/page-to-go-to"/>

للقيام بالتنقل برمجيًا ، تحتاج إلى دفع محفوظات جديدة إلى props.history في component الخاص بك ، لذلك يمكن لمثل هذا أن يقوم بالعمل نيابة عنك:

 import { Router, Route, IndexRedirect, browserHistory } from 'react-router'

 render(<Router history={browserHistory}>
          <Route path='/' component={ParentComp}>
            <IndexRedirect to = "/login"/>
            <Route path='/login' component={LoginComp}/>
            <Route path='/home' component={HomeComp}/>
            <Route path='/repair' component={RepairJobComp} />
            <Route path='/service' component={ServiceJobComp} />
          </Route>
        </Router>, document.getElementById('root'));


رد فعل بسيط التوجيه:

رابط لبلدي رمل رمز. لديها عدد قليل من برامج رد فعل رد الفعل البسيطة.





react-router