react-router를 사용하여 다른 경로로 리디렉션하는 방법은 무엇입니까?


95

다른 뷰로 리디렉션하기 위해 react-router ( 버전 ^ 1.0.3 )를 사용하여 A SIMPLE을 수행하려고하는데 피곤해집니다.

import React from 'react';
import {Router, Route, Link, RouteHandler} from 'react-router';


class HomeSection extends React.Component {

  static contextTypes = {
    router: PropTypes.func.isRequired
  };

  constructor(props, context) {
    super(props, context);
  }

  handleClick = () => {
    console.log('HERE!', this.contextTypes);
    // this.context.location.transitionTo('login');
  };

  render() {
    return (
      <Grid>
        <Row className="text-center">          
          <Col md={12} xs={12}>
            <div className="input-group">
              <span className="input-group-btn">
                <button onClick={this.handleClick} type="button">
                </button>
              </span>
            </div>
          </Col>
        </Row>
      </Grid>
    );
  }
};

HomeSection.contextTypes = {
  location() {
    React.PropTypes.func.isRequired
  }
}

export default HomeSection;

내가 필요한 것은 '/ 로그인'에 사용을 보내는 것뿐입니다.

어떡해 ?

콘솔 오류 :

포착되지 않은 ReferenceError : PropTypes가 정의되지 않았습니다.

내 경로를 기록

// LIBRARY
/*eslint-disable no-unused-vars*/
import React from 'react';
/*eslint-enable no-unused-vars*/
import {Route, IndexRoute} from 'react-router';

// COMPONENT
import Application from './components/App/App';
import Contact from './components/ContactSection/Contact';
import HomeSection from './components/HomeSection/HomeSection';
import NotFoundSection from './components/NotFoundSection/NotFoundSection';
import TodoSection from './components/TodoSection/TodoSection';
import LoginForm from './components/LoginForm/LoginForm';
import SignupForm from './components/SignupForm/SignupForm';

export default (
    <Route component={Application} path='/'>
      <IndexRoute component={HomeSection} />
      <Route component={HomeSection} path='home' />
      <Route component={TodoSection} path='todo' />
      <Route component={Contact} path='contact' />
      <Route component={LoginForm} path='login' />
      <Route component={SignupForm} path='signup' />
      <Route component={NotFoundSection} path='*' />
    </Route>
);

안녕하세요! routes정의 를 게시 할 수 있으며 Link구성 요소를 사용하지 않는 이유가있는 경우에도 게시 할 수 있습니까 ? 또한 어떤 오류가 발생하는지 언급하십시오.
aarosil

버튼 대신 <Link to="/login">Log In</Link>?
aarosil

또한 어떤 버전의 react-router를 사용하고 있습니까? 절차 적 리디렉션 코드는 주요 버전간에 변경되었습니다.
mjhm

4
를 들어 Uncaught ReferenceError, 당신이 같은 요구하고있다 PropTypes,하지만 당신은 그것을 가져올 수 없습니다, 당신은 그 자체 또는 사용으로 PropTypes를 가져올 필요React.PropTypes
aarosil

1
나는 놀라지 않을 것이다 그러나 @JoshDavidMiller 좋은 점 react-router5 분 이내에 API를 변화 .. 단지 부분적으로 하하 농담,하지만
aarosil

답변:


33

간단한 대답을 위해 대신 Link에서 구성 요소를 사용할 수 있습니다 . JS에서 경로를 변경하는 방법이 있지만 여기서는 필요하지 않은 것 같습니다.react-routerbutton

<span className="input-group-btn">
  <Link to="/login" />Click to login</Link>
</span>

1.0.x에서 프로그래밍 방식으로 수행하려면 clickHandler 함수 내에서 다음과 같이합니다.

this.history.pushState(null, 'login');

여기 업그레이드 문서 에서 가져옴

당신은해야 this.history하여 경로 처리기 구성 요소에 배치 react-router. routes정의에 언급 된 하위 구성 요소 아래에있는 경우 추가로 전달해야 할 수 있습니다.


2
이것은 멋진 해결책이지만, 제가 그것을 사용하지 않는 이유는 먼저 일종의 유효성 검사를해야하기 if (true) { // redirect to login}때문입니다 . 그래서 이것을 함수에 넣어야합니다. function
Reacting

5
JSX에서 할 수도 있습니다 : {validation && <Link to="/login" />Click to login</Link>}. 유효성 검사가 거짓이면 아무 것도 렌더링되지 않습니다.
aarosil

무슨 뜻인지 알지만, 유효성 검사가 참이면 버튼이 있어야합니다. 리디렉션하면 오류 메시지가 나타납니다.
반응

내가 JS에 그것을 할 방법을 보여 대답 업데이트 @TheUnnamed
aarosil

1
> Uncaught TypeError : Cannot read property 'pushState'of undefined
Reacting

94

1) 반응 라우터> V5 useHistory후크 :

React >= 16.8기능적인 구성 요소 가있는 경우 useHistory react-router후크를 사용할 수 있습니다 .

import React from 'react';
import { useHistory } from 'react-router-dom';

const YourComponent = () => {
    const history = useHistory();

    const handleClick = () => {
        history.push("/path/to/push");
    }

    return (
        <div>
            <button onClick={handleClick} type="button" />
        </div>
    );
}

export default YourComponent;

2) 반응 라우터> V4 withRouterHOC :

@ambar가 주석에서 언급했듯이 React-router는 V4 이후로 코드 기반을 변경했습니다. 여기에 문서화입니다 - 공식 , withRouter

import React, { Component } from 'react';
import { withRouter } from "react-router-dom";

class YourComponent extends Component {
    handleClick = () => {
        this.props.history.push("path/to/push");
    }

    render() {
        return (
            <div>
                <button onClick={this.handleClick} type="button">
            </div>
        );
    };
}

export default withRouter(YourComponent);

3) React-router <V4 with browserHistory

react-router를 사용하여이 기능을 수행 할 수 있습니다 BrowserHistory. 아래 코드 :

import React, { Component } from 'react';
import { browserHistory } from 'react-router';

export default class YourComponent extends Component {
    handleClick = () => {
        browserHistory.push('/login');
    };

    render() {
        return (
            <div>
                <button onClick={this.handleClick} type="button">
            </div>
        );
    };
}

4) Redux connected-react-router

당신이 REDUX와 구성 요소를 연결 한 및 구성한 경우 연결-반응 라우터 당신이해야 할 모든 것입니다 this.props.history.push("/new/url");즉, 당신은 필요가 없습니다 withRouter주입 HOC를 history구성 요소 소품에.

// reducers.js
import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router';

export default (history) => combineReducers({
    router: connectRouter(history),
    ... // rest of your reducers
});


// configureStore.js
import { createBrowserHistory } from 'history';
import { applyMiddleware, compose, createStore } from 'redux';
import { routerMiddleware } from 'connected-react-router';
import createRootReducer from './reducers';
...
export const history = createBrowserHistory();

export default function configureStore(preloadedState) {
    const store = createStore(
        createRootReducer(history), // root reducer with router state
        preloadedState,
        compose(
            applyMiddleware(
                routerMiddleware(history), // for dispatching history actions
                // ... other middlewares ...
            ),
        ),
    );

    return store;
}


// set up other redux requirements like for eg. in index.js
import { Provider } from 'react-redux';
import { Route, Switch } from 'react-router';
import { ConnectedRouter } from 'connected-react-router';
import configureStore, { history } from './configureStore';
...
const store = configureStore(/* provide initial state if any */)

ReactDOM.render(
    <Provider store={store}>
        <ConnectedRouter history={history}>
            <> { /* your usual react-router v4/v5 routing */ }
                <Switch>
                    <Route exact path="/yourPath" component={YourComponent} />
                </Switch>
            </>
        </ConnectedRouter>
    </Provider>,
    document.getElementById('root')
);


// YourComponent.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
...

class YourComponent extends Component {
    handleClick = () => {
        this.props.history.push("path/to/push");
    }

    render() {
        return (
          <div>
            <button onClick={this.handleClick} type="button">
          </div>
        );
      }
    };

}

export default connect(mapStateToProps = {}, mapDispatchToProps = {})(YourComponent);

3
'browserHistory'가 더 이상 반응 라우터의 일부가 아닌 것 같습니다.
ambar

BrowserRouter 푸시 기능이 없습니다
johnnyodonnell

@ambar @johnnyodonnell react-router-dom않습니다
toinetoine

이것이 최고의 답변입니다. 이것을 올바른 것으로 표시해야합니다.
솔로몬 부시

23

react-router를 사용하여 다른 경로로 리디렉션하는 방법은 무엇입니까?

예를 들어 사용자가 링크를 클릭하면 <Link to="/" />Click to route</Link>react-router가 찾아서 로그인 경로와 같은 다른 곳에서 사용자를 /사용 Redirect to하고 보낼 수 있습니다 .

ReactRouterTraining에 대한 문서 에서 :

를 렌더링하면 <Redirect>새 위치로 이동합니다. 새 위치는 서버 측 리디렉션 (HTTP 3xx)과 마찬가지로 기록 스택의 현재 위치를 재정의합니다.

import { Route, Redirect } from 'react-router'

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>

to : string, 리디렉션 할 URL입니다.

<Redirect to="/somewhere/else"/>

to : object, 리디렉션 할 위치입니다.

<Redirect to={{
  pathname: '/login',
  search: '?utm=your+face',
  state: { referrer: currentLocation }
}}/>

제공된 솔루션에서 오류가 발생 <Redirect> elements are for router configuration only and should not be rendered합니다.
t1gor

10

가장 쉬움웹을위한 솔루션!

2020 년까지 다음
작업을 확인했습니다.

"react-router-dom": "^5.1.2"
"react": "^16.10.2"

useHistory()후크를 사용하십시오 !

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


export function HomeSection() {
  const history = useHistory();
  const goLogin = () => history.push('login');

  return (
    <Grid>
      <Row className="text-center">          
        <Col md={12} xs={12}>
          <div className="input-group">
            <span className="input-group-btn">
              <button onClick={goLogin} type="button" />
            </span>
          </div>
        </Col>
      </Row>
    </Grid>
  );
}

훌륭합니다. 후크 방법을 찾고있었습니다! 내 IDE에서 "Cannot resolve symbol ..."경고가 표시되지만 작동합니다!
Rafael Moni

7

react-router v2.8.1 (아마 다른 2.xx 버전도 있지만 테스트하지는 않았 음)을 사용하면이 구현을 사용하여 라우터 리디렉션을 수행 할 수 있습니다.

import { Router } from 'react-router';

export default class Foo extends Component {

  static get contextTypes() {
    return {
      router: React.PropTypes.object.isRequired,
    };
  }

  handleClick() {
    this.context.router.push('/some-path');
  }
}

가끔 : this.context.router.history.push ( '/ some-path');
象嘉道

4

가장 간단한 해결책은 다음과 같습니다.

import { Redirect } from 'react-router';

<Redirect to='/componentURL' />

하지만 오류가 발생합니다 : Invariant failed : <Router> 외부에서 <Redirect>를 사용하면 안됩니다
Prateek Gupta

포장하려고 했습니까?
Jackkobec
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.