programing

리액트 라우터 v4에서 이력 푸시 방법

showcode 2023. 3. 11. 09:39
반응형

리액트 라우터 v4에서 이력 푸시 방법

리액트라우터에서는 서버의 「」(v3)를 사용할 수 .browserHistory.push적절한 응답 페이지로 이동합니다.그러나 v4에서는 사용할 수 없기 때문에 어떻게 대처해야 할지 잘 모르겠습니다.

이 예에서는 Redx를 사용하여 컴포넌트/app-product-form.js를 호출합니다.this.props.addProduct(props)사용자가 양식을 제출할 때.서버가 성공을 반환하면 사용자는 Cart 페이지로 이동합니다.

// actions/index.js
export function addProduct(props) {
  return dispatch =>
    axios.post(`${ROOT_URL}/cart`, props, config)
      .then(response => {
        dispatch({ type: types.AUTH_USER });
        localStorage.setItem('token', response.data.token);
        browserHistory.push('/cart'); // no longer in React Router V4
      });
}

리액트 라우터 v4의 기능에서 카트 페이지로 리다이렉트하려면 어떻게 해야 합니까?

.history이치노이치노

'만들기'를 .history오브젝트가 이력 패키지를 사용했습니다.

// src/history.js

import { createBrowserHistory } from 'history';

export default createBrowserHistory();

it it로 감아주세요.<Router>(주의:import { Router }import { BrowserRouter as Router }

// src/index.jsx

// ...
import { Router, Route, Link } from 'react-router-dom';
import history from './history';

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/login">Login</Link></li>
        </ul>
        <Route exact path="/" component={HomePage} />
        <Route path="/login" component={LoginPage} />
      </div>
    </Router>
  </Provider>,
  document.getElementById('root'),
);

원하는 위치에서 현재 위치를 변경할 수 있습니다. 예를 들어 다음과 같습니다.

// src/actions/userActionCreators.js

// ...
import history from '../history';

export function login(credentials) {
  return function (dispatch) {
    return loginRemotely(credentials)
      .then((response) => {
        // ...
        history.push('/');
      });
  };
}

UPD: 리액트 라우터 FAQ에서도 약간 다른 예를 볼 수 있습니다.

라우터 이전의에 리액트 라우터 v4 v3(이전의 경우)는 할 수 .browserHistory.push()예전처럼 말이야

자세한 내용을 알고 싶다면 이 토론이 관련된 것 같습니다.

  • 「」의 browserHistory 않다<BrowserRouter>는 자체 이력 인스턴스를 생성하여 변경 내용을 수신합니다. 다른 하지만 URL은 되지 않습니다.<BrowserRouter>.
  • browserHistory에 의해 되지 않고 v4에서는 react-display에 만 노출됩니다.

대신 몇 가지 옵션을 사용할 수 있습니다.

  • 하다를 사용하세요.withRouter

    대를 .withRouter상위 컴포넌트를 이력까지 푸시하는 컴포넌트로 랩합니다.예를 들어 다음과 같습니다.

    import React from "react";
    import { withRouter } from "react-router-dom";
    
    class MyComponent extends React.Component {
      ...
      myFunction() {
        this.props.history.push("/some/Path");
      }
      ...
    }
    export default withRouter(MyComponent);
    

    자세한 내용은 다음 공식 문서를 참조하십시오.

    withRouter 고차 컴포넌트를 통해 객체의 속성 및 가장 가까운 에 액세스할 수 있습니다.withRouter는 렌더링 소품과 같은 소품으로 루트가 변경될 때마다 컴포넌트를 다시 렌더링합니다.{ match, location, history }.


  • 하다를 사용하세요.context

    콘텍스트를 사용하는 것이 가장 쉬운 해결책 중 하나일 수 있지만 실험 API이기 때문에 불안정하고 지원되지 않습니다.다른 모든 것이 실패할 때만 사용하십시오.다음은 예를 제시하겠습니다.

    import React from "react";
    import PropTypes from "prop-types";
    
    class MyComponent extends React.Component {
      static contextTypes = {
        router: PropTypes.object
      }
      constructor(props, context) {
         super(props, context);
      }
      ...
      myFunction() {
        this.context.router.history.push("/some/Path");
      }
      ...
    }
    

    콘텍스트에 관한 공식 문서를 참조해 주세요.

    애플리케이션의 안정성을 유지하려면 컨텍스트를 사용하지 마십시오.이것은 실험적인 API이며 향후 React 릴리즈에서 중단될 가능성이 있습니다.

    이러한 경고에도 불구하고 콘텍스트 사용을 고집하는 경우 콘텍스트 사용을 좁은 영역으로 격리하고 가능하면 콘텍스트 API를 직접 사용하지 않도록 하십시오.그러면 API가 변경되었을 때 업그레이드가 쉬워집니다.

react-router v5에서는 다음과 같이 useHistory 훅을 사용할 수 있습니다.

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

function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.push("/home");
  }

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

자세한 것은, https://reacttraining.com/react-router/web/api/Hooks/usehistory 를 참조해 주세요.

React Router 4에서 가장 간단한 방법은

this.props.history.push('/new/url');

그러나 이 방법을 사용하려면 기존 컴포넌트에서history we. 음다다다다다다다다다다다다다다다다다다다다다다다다다.

  1. 가 에 Route는 이미 할 수 .history★★★★★★ 。

    예:

    <Route path="/profile" component={ViewProfile}/>
    

    서 ★★★★ViewProfile 할 수 .history.

  2. 않은 Route직접적으로.

    예:

    <Route path="/users" render={() => <ViewUsers/>}
    

    '우리'를 써야 요.withRouter★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    . ViewUsers컴포넌트 요 component

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

    • export default withRouter(ViewUsers);

    ViewUsers는 '할 수 있다'에 액세스 할 수 .history★★★★★★ 。

갱신하다

2이에서는 모든 합니다. - 모든 경로를 통과합니다.props할 수 .this.props.history로부터는, 「컴포넌트」를 .HOC

예:

<Route path="/users" render={props => <ViewUsers {...props} />}

저는 이렇게 했습니다.

import React, {Component} from 'react';

export default class Link extends Component {
    constructor(props) {
        super(props);
        this.onLogout = this.onLogout.bind(this);
    }
    onLogout() {
        this.props.history.push('/');
    }
    render() {
        return (
            <div>
                <h1>Your Links</h1>
                <button onClick={this.onLogout}>Logout</button>
            </div>
        );
    }
}

this.props.history.push('/cart');카트의 페이지로 리다이렉트 하려면 , 이력 오브젝트에 보존됩니다.

즐겨라, 마이클

React Router v4 매뉴얼에 따르면 Redex Deep Integration 세션

다음을 위해서는 긴밀한 통합이 필요합니다.

"액션을 디스패치하여 네비게이트 할 수 있다"

다만, 「심층적인 통합」의 대안으로서 이 어프로치를 추천하고 있습니다.

조작을 디스패치하여 네비게이트하는 것이 아니라 컴포넌트를 조작으로 라우팅하기 위해 제공된 이력 객체를 전달하여 조작으로 네비게이트할 수 있습니다.

따라서 컴포넌트를 라우터의 상위 컴포넌트로 랩할 수 있습니다.

export default withRouter(connect(null, { actionCreatorName })(ReactComponent));

역사 API를 소품으로 전달합니다.따라서 이력을 매개 변수로 전달하는 작업 작성자를 호출할 수 있습니다.예를 들어 React Component 내부:

onClick={() => {
  this.props.actionCreatorName(
    this.props.history,
    otherParams
  );
}}

다음으로 actions/index.js 내에서 다음을 수행합니다.

export function actionCreatorName(history, param) {
  return dispatch => {
    dispatch({
      type: SOME_ACTION,
      payload: param.data
    });
    history.push("/path");
  };
}

귀찮은 질문이라 시간이 많이 걸렸지만 결국엔 이렇게 해결했어요

를 테테로 합니다.withRouter해 주세요.mapDispatchToProps.push')를 사용하여네비게이트합니다.역사/url')을 사용하다

액션:

export function saveData(history, data) {
  fetch.post('/save', data)
     .then((response) => {
       ...
       history.push('/url');
     })
};

컨테이너:

import { withRouter } from 'react-router-dom';
...
const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    save: (data) => dispatch(saveData(ownProps.history, data))}
};
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Container));

이것은 React Router v4.x에서 유효합니다.

다른 사람에게 가치가 있는 해결책 하나를 더 제안합니다.

는 나나 a a a가 있다history.js다음과 같이 합니다.

import createHistory from 'history/createBrowserHistory'
const history = createHistory()
history.pushLater = (...args) => setImmediate(() => history.push(...args))
export default history

다음으로 라우터를 정의하는 루트에서 다음을 사용합니다.

import history from '../history'
import { Provider } from 'react-redux'
import { Router, Route, Switch } from 'react-router-dom'

export default class Root extends React.Component {
  render() {
    return (
     <Provider store={store}>
      <Router history={history}>
       <Switch>
        ...
       </Switch>
      </Router>
     </Provider>
    )
   }
  }

마침내, 나의 위에actions.js를 Import하여 합니다.

import history from './history'
export const login = createAction(
...
history.pushLater({ pathname: PATH_REDIRECT_LOGIN })
...)

이렇게 하면 API 호출 후 새로운 액션을 푸시할 수 있습니다.

도움이 됐으면 좋겠다!

this.context.history.push동작하지 않습니다.

나는 이렇게 일을 추진해 낼 수 있었다.

static contextTypes = {
    router: PropTypes.object
}

handleSubmit(e) {
    e.preventDefault();

    if (this.props.auth.success) {
        this.context.router.history.push("/some/Path")
    }

}

사용하지 않도록 조심해라react-router@5.2.0 ★★★★★★★★★★★★★★★★★」react-router-dom@5.2.0history@5.0.0. URL은 다음 시간 후에 갱신됩니다.history.push 다른 하지 않습니다.react-router을 사용하다npm install history@4.10.1이력 버전을 변경합니다.자세한 내용은 v 5로 업그레이드한 후 리액트 라우터가 작동하지 않음을 참조하십시오.

, 예를 들면,이렇게 하다」를 사용합니다.<NavLink to="/apps">에서 NavLink.js를 소비하는 .<RouterContext.Consumer>context.location이력을 푸시할 때 작업 및 위치 속성을 가진 개체로 변경합니다. ★★★★★★★★★★★★★★★★★.currentLocation.pathname무효로 하다

이 경우 당신은 당신의 덩크에게 소품을 건네는 것입니다.전화만 하면 됩니다.

props.history.push('/cart')

그렇지 않은 경우에도 컴포넌트에서 이력을 전달할 수 있습니다.

export function addProduct(data, history) {
  return dispatch => {
    axios.post('/url', data).then((response) => {
      dispatch({ type: types.AUTH_USER })
      history.push('/cart')
    })
  }
}

나는 같은 주제로 고민했다.react-router-dom 5, Redux 4, BrowserRouter를 사용하고 있습니다.기능 기반의 컴포넌트와 후크를 선호합니다.

컴포넌트를 다음과 같이 정의합니다.

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

const Component = () => {
  ...
  const history = useHistory();
  dispatch(myActionCreator(otherValues, history));
};

그리고 당신의 액션 크리에이터는

const myActionCreator = (otherValues, history) => async (dispatch) => {
  ...
  history.push("/path");
}

물론 비동기화가 필요하지 않은 경우 보다 간단한 작업 생성기를 사용할 수 있습니다.

제 )는 사용하지 react-router-redux

const store = configureStore()
const customHistory = createBrowserHistory({
  basename: config.urlBasename || ''
})

ReactDOM.render(
  <Provider store={store}>
    <Router history={customHistory}>
      <Route component={({history}) => {
        window.appHistory = history
        return (
          <App />
        )
      }}/>
    </Router>
  </Provider>,
  document.getElementById('root')
)

하면 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.window.appHistory.push()원하는 곳(예: 레덕스 스토어 기능/스턱스/사가 등)을 사용할 수 있으면 좋겠다고 생각했습니다.window.customHistory.push() 어떤 react-router 것 .url은 갱신되지 않습니다., 하면 인스턴스가 됩니다.react-router글로벌 스코프에 넣는 것을 좋아하지 않습니다.또, 이것은, 제가 가지고 있는 몇개의 일 중 하나입니다. IMO는지금까지더 것 같아요.

Redux를 사용하고 있다면 npm 패키지 react-router-redux를 사용하는 것을 추천합니다.이를 통해 Redx 스토어 탐색 작업을 디스패치할 수 있습니다.

Readme 파일에 설명된 대로 스토어를 생성해야 합니다.

가장 쉬운 사용 사례:

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

this.props.dispatch(push('/second page'));

컨테이너/컴포넌트의 두 번째 사용 사례:

컨테이너:

import { connect } from 'react-redux';
import { push } from 'react-router-redux';

import Form from '../components/Form';

const mapDispatchToProps = dispatch => ({
  changeUrl: url => dispatch(push(url)),
});

export default connect(null, mapDispatchToProps)(Form);

컴포넌트:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

export default class Form extends Component {
  handleClick = () => {
    this.props.changeUrl('/secondPage');
  };

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

하려면 , 「이것」을 사용해 주세요.bind()버튼을 하고 싶어서index.jsx후 "데이터를 투고하다"로 합니다.success.jsx★★★★★★★★★★★★★★★★★★★。

index.jsx:

import React, { Component } from "react"
import { postData } from "../../scripts/request"

class Main extends Component {
    constructor(props) {
        super(props)
        this.handleClick = this.handleClick.bind(this)
        this.postData = postData.bind(this)
    }

    handleClick() {
        const data = {
            "first_name": "Test",
            "last_name": "Guy",
            "email": "test@test.com"
        }

        this.postData("person", data)
    }

    render() {
        return (
            <div className="Main">
                <button onClick={this.handleClick}>Test Post</button>
            </div>
        )
    }
}

export default Main

request.js:

import { post } from "./fetch"

export const postData = function(url, data) {
    // post is a fetch() in another script...
    post(url, data)
        .then((result) => {
            if (result.status === "ok") {
                this.props.history.push("/success")
            }
        })
}

success.jsx:

import React from "react"

const Success = () => {
    return (
        <div className="Success">
            Hey cool, got it.
        </div>
    )
}

export default Success

래래 so so so so so so so so를 묶어서this로로 합니다.postDataindex.jsx에할 수 있었습니다.this.props.historyrequest.js이 기능을 할 수 해야 할 은...다른 컴포넌트에서 이 기능을 재사용할 수 있습니다.기억할 필요가 있습니다.this.postData = postData.bind(this) constructor().

리다이렉트 할 때 - 할 때 - 리다이렉트 할 때 - 리다이렉트 할 때 - 리다이렉트 할 때 - 리다이렉트 할 때history.push , 을 사용합니다.Redirectreact-router-dom는 그냥 .push=true

import * as React from 'react';
import { Redirect } from 'react-router-dom';
class Example extends React.Component {
  componentDidMount() {
    this.setState({
      redirectTo: '/test/path'
    });
  }

  render() {
    const { redirectTo } = this.state;

    return <Redirect to={{pathname: redirectTo}} push={true}/>
  }
}

콜백을 사용합니다.나한텐 효과가 있었어!

export function addProduct(props, callback) {
  return dispatch =>
    axios.post(`${ROOT_URL}/cart`, props, config)
    .then(response => {
    dispatch({ type: types.AUTH_USER });
    localStorage.setItem('token', response.data.token);
    callback();
  });
}

컴포넌트에서는 콜백을 추가하기만 하면 됩니다.

this.props.addProduct(props, () => this.props.history.push('/cart'))

리액트 라우터 V4에서는 다음과 같이 이력 소품을 사용할 수 있게 되었습니다.

this.props.history.push("/dummy",value)

할 수 있는 모든 할 수 .이러한 값은 로케이션프롭을 사용할 수 있습니다.state:{value}컴포넌트 상태가 아닙니다.

리액트 라우터 5에 이미 이력이 포함되어 있기 때문에 참조를 통해 이 이 이력에 액세스 할 수 있습니다.

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

function App() {
   const routerRef = React.useRef();
   const onProductNav = () => {
       const history = routerRef.current.history;
       history.push("product");
   }
return (
    <BrowserRouter ref={routerRef}>
        <Switch>
            <Route path="/product">
                <ProductComponent />
            </Route>
            <Route path="/">
                <HomeComponent />
            </Route>
        </Switch>
    </BrowserRouter>
)
}

1단계 라우터에서 앱을 랩합니다.

import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.render(<Router><App /></Router>, document.getElementById('root'));

이제 앱 전체가 BrowserRouter에 액세스할 수 있게 되었습니다.2단계 루트를 가져오고 소품을 전달합니다.아마 당신의 주요 파일 중 하나에 있을 겁니다.

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

//lots of code here

//somewhere in my render function

    <Route
      exact
      path="/" //put what your file path is here
      render={props => (
      <div>
        <NameOfComponent
          {...props} //this will pass down your match, history, location objects
        />
      </div>
      )}
    />

컴포넌트 js 파일에서 console.log(this.props)를 실행하면 다음과 같은 것을 얻을 수 있습니다.

{match: {…}, location: {…}, history: {…}, //other stuff }

2단계 이력 오브젝트에 접속하여 위치를 변경할 수 있습니다.

//lots of code here relating to my whatever request I just ran delete, put so on

this.props.history.push("/") // then put in whatever url you want to go to

그리고 난 코딩 부트캠프 학생일 뿐이니까 전문가는 아니지만

window.location = "/" //wherever you want to go

틀렸다면 정정해 주세요만, 테스트 결과, React의 사용 포인트 전체를 무효로 한 페이지 전체가 새로고침 되었습니다.

「」을 합니다.Router 나름의browserHistory:

import React from 'react';
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';

export const history = createBrowserHistory();

const ExtBrowserRouter = ({children}) => (
  <Router history={history} >
  { children }
  </Router>
);

export default ExtBrowserRouter

다음 '에서 '뿌리'를 하는 부분에서는 '뿌리'를 쓰겠습니다.Router , , 를합니다.

import React from 'react';       
import { /*BrowserRouter,*/ Route, Switch, Redirect } from 'react-router-dom';

//Use 'ExtBrowserRouter' instead of 'BrowserRouter'
import ExtBrowserRouter from './ExtBrowserRouter'; 
...

export default class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <ExtBrowserRouter>
          <Switch>
            ...
            <Route path="/login" component={Login}  />
            ...
          </Switch>
        </ExtBrowserRouter>
      </Provider>
    )
  }
}

Import( Import)history필요한 장소에서 사용할 수 있습니다.

import { history } from '../routers/ExtBrowserRouter';
...

export function logout(){
  clearTokens();      
  history.push('/login'); //WORKS AS EXPECTED!
  return Promise.reject('Refresh token has expired');
}

내가 로그인과 매니에 다른 것들을 하기 때문에 너는 이렇게 사용할 수 있다.

class Login extends Component {
  constructor(props){
    super(props);
    this.login=this.login.bind(this)
  }


  login(){
this.props.history.push('/dashboard');
  }


render() {

    return (

   <div>
    <button onClick={this.login}>login</login>
    </div>

)
/*Step 1*/
myFunction(){  this.props.history.push("/home"); }
/**/
 <button onClick={()=>this.myFunction()} className={'btn btn-primary'}>Go 
 Home</button>

기능을 컴포넌트의 프로포트에 값으로 전달하면서 이력을 사용하고 싶다면 리액트 라우터 4를 사용하여 이력을 구축하기만 하면 됩니다.history<Route/>[ Component ]를하여 [Component]를 선택합니다.history.push()

    <Route path='/create' render={({history}) => (
      <YourComponent
        YourProp={() => {
          this.YourClassMethod()
          history.push('/')
        }}>
      </YourComponent>
    )} />

주의: 이 작업을 수행하려면 Respect Router의 BrowserRouter 구성 요소를 루트 구성 요소(index.js에 있을 수 있음)에 감아야 합니다.

언급URL : https://stackoverflow.com/questions/42701129/how-to-push-to-history-in-react-router-v4

반응형