[reactjs] 반응 라우터 V4를 사용하여 프로그래밍 방식으로 탐색
방금 react-routerv3에서 v4 로 교체 했습니다.
그러나의 멤버 함수에서 프로그래밍 방식으로 탐색하는 방법을 잘 모르겠습니다 Component. 즉 handleClick()기능 에서 /path/some/where일부 데이터를 처리 한 후 탐색하고 싶습니다 . 나는 다음과 같이 그것을 사용했다.
import { browserHistory } from 'react-router'
browserHistory.push('/path/some/where')
그러나 v4에서 이러한 인터페이스를 찾을 수 없습니다.
v4를 사용하여 탐색하려면 어떻게해야합니까?
답변
브라우저 환경을 대상으로하는 경우 react-router-dom대신 패키지 를 사용해야 합니다 react-router. 이들은 두 개의 개별 패키지를 설치할 필요가 없다는 미묘한 차이로 코어 ( react)와 플랫폼 별 코드 ( react-dom, react-native) 를 분리하기 위해 React와 동일한 접근 방식을 따르고 있으므로 환경 패키지에 모든 것이 포함됩니다. 당신은 필요합니다. 다음과 같이 프로젝트에 추가 할 수 있습니다.
yarn add react-router-dom
또는
npm i react-router-dom
가장 먼저해야 할 일은 <BrowserRouter>응용 프로그램에서 가장 상위 상위 구성 요소로 제공하는 것입니다. <BrowserRouter>HTML5 historyAPI를 사용하고 관리하므로 직접 인스턴스화하여 <BrowserRouter>구성 요소에 소품으로 전달할 필요가 없습니다 (이전 버전에서와 같이).
V4에서는 프로 그래 매틱 방식으로 탐색하려면 애플리케이션에서 최상위 컴포넌트로 제공자 컴포넌트 가있는 한 historyReact를 통해 사용 가능한 오브젝트 에 액세스 해야합니다. 라이브러리는 컨텍스트를 통해 개체 자체를 속성으로 포함 합니다. 인터페이스는 다음과 같은 여러 가지 탐색 방법을 제공합니다 , 그리고 다른 사람의 사이에서. 여기 에서 전체 속성 및 메서드 목록을 확인할 수 있습니다 .context<BrowserRouter> routerhistoryhistorypushreplacegoBack
Redux / Mobx 사용자에게 중요한 참고 사항
애플리케이션에서 redux 또는 mobx를 상태 관리 라이브러리로 사용하는 경우 위치를 인식해야하지만 URL 업데이트를 트리거 한 후 다시 렌더링되지 않는 구성 요소 관련 문제가 발생할 수 있습니다.
컨텍스트 모델을 사용하여 구성 요소로 react-router전달 location하기 때문에 발생 합니다.
connect와 observer는 shouldComponentUpdate 메소드가 현재 props와 다음 props를 얕게 비교하는 컴포넌트를 만듭니다. 해당 구성 요소는 하나 이상의 소품이 변경된 경우에만 다시 렌더링됩니다. 즉, 위치가 변경 될 때 업데이트되도록하려면 위치가 변경 될 때 변경되는 소품이 제공되어야합니다.
이를 해결하기위한 두 가지 접근 방식은 다음과 같습니다.
- 당신의 랩 연결된 길이없는에서 구성 요소를
<Route />. 현재location객체는<Route>렌더링하는 구성 요소에 전달 하는 소품 중 하나입니다. - 연결된 컴포넌트를
withRouter고차 컴포넌트로 감싸십시오 . 실제로는location소품 과 동일한 효과가 있고 주입 됩니다.
이를 제외하고 권장 사항에 따라 순서대로 프로그래밍 방식으로 탐색하는 네 가지 방법이 있습니다.
1.- <Route>컴포넌트 사용
선언적 스타일을 촉진합니다. v4 이전에는 <Route />구성 요소가 구성 요소 계층의 맨 위에 배치 되었으므로 미리 경로 구조를 고려해야했습니다. 그러나 이제 트리의 어느 위치 에나<Route> 구성 요소 를 배치 할 수 있으므로 URL에 따라 조건부 렌더링을보다 세밀하게 제어 할 수 있습니다. 를 분사 , 및 구성 요소에 소품으로. 탐색 방법 (예를 들면 , , …)의 특성으로서 사용할 수있는 개체.RoutematchlocationhistorypushreplacegoBackhistory
, 또는 props Route를 사용 하여을 사용하여 무언가를 렌더링하는 방법에는 3 가지가 있지만, 같은 것을 여러 개 사용하지 마십시오 . 선택은 유스 케이스에 따라 다르지만 기본적으로 처음 두 옵션은 URL 위치와 일치하는 경우에만 컴포넌트를 렌더링 하는 반면 , 컴포넌트 와 함께 경로가 위치와 일치하는지 여부는 렌더링됩니다 (URL을 기반으로 UI를 조정하는 데 유용함) 어울리는).componentrenderchildrenRoutepathchildren
컴포넌트 렌더링 출력을 사용자 정의render 하려면 match, location및을 제외한 원하는 다른 소품을 컴포넌트에 전달하려면 컴포넌트를 함수로 감싸고 옵션을 사용해야합니다 history. 설명하는 예 :
import { BrowserRouter as Router } from 'react-router-dom'
const ButtonToNavigate = ({ title, history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
{title}
</button>
);
const SomeComponent = () => (
<Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)
const App = () => (
<Router>
<SomeComponent /> // Notice how in v4 we can have any other component interleaved
<AnotherComponent />
</Router>
);
withRouterHoC 사용
이 고차 컴포넌트는와 같은 소품을 주입합니다 Route. 그러나 파일 당 하나의 HoC 만 가질 수 있다는 제한이 따릅니다.
import { withRouter } from 'react-router-dom'
const ButtonToNavigate = ({ history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
Navigate
</button>
);
ButtonToNavigate.propTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired,
}),
};
export default withRouter(ButtonToNavigate);
Redirect구성 요소 사용
를 렌더링하면 <Redirect>새 위치로 이동합니다. 그러나 기본적으로 현재 위치는 서버 측 리디렉션 (HTTP 3xx)과 같은 새로운 위치로 대체됩니다. 새 위치는 toprop 에 의해 제공되며 문자열 (리디렉션 할 URL) 또는 location객체 일 수 있습니다. 새 항목을 히스토리 로 푸시하려면push 소품도 전달 하고로 설정하십시오.true
<Redirect to="/your-new-location" push />
router컨텍스트를 통해 수동으로 액세스
컨텍스트 는 여전히 실험적인 API이므로 React의 향후 릴리스에서 중단 / 변경 될 가능성이 있기 때문에 약간 실망 했습니다.
const ButtonToNavigate = (props, context) => (
<button
type="button"
onClick={() => context.router.history.push('/my-new-location')}
>
Navigate to a new location
</button>
);
ButtonToNavigate.contextTypes = {
router: React.PropTypes.shape({
history: React.PropTypes.object.isRequired,
}),
};
말할 것도없이 메모리에<NativeRouter> 탐색 스택을 복제하고 패키지를 통해 사용 가능한 React Native 플랫폼을 대상 으로 하는 것과 같은 비 브라우저 에코 시스템을위한 다른 라우터 구성 요소도 있습니다 .react-router-native
자세한 내용은 공식 문서를 참조하십시오 . 라이브러리의 공동 저자 중 한 명이 반응 라우터 v4에 대한 멋진 소개를 제공 하는 비디오 가 있으며 주요 변경 사항 중 일부를 강조 표시합니다.
답변
가장 쉬운 방법은 다음과 같습니다.
this.props.history.push("/new/url")
노트 :
historyprop사용 불가능한 경우 상위 컴포넌트에서 조치를 호출하려는 컴포넌트로 전달할 수 있습니다.
답변
React-Router v4로 마이그레이션 할 때 비슷한 문제가 발생하여 아래에서 솔루션을 설명하려고 시도합니다.
이 답변을 문제를 해결하는 올바른 방법으로 생각하지 마십시오 .React Router v4가 성숙 해지고 베타 버전을 떠날 때 더 나은 결과가 발생할 가능성이 있다고 생각합니다 (이미 존재하더라도 발견하지 못했습니다) .
상황에 따라, 때때로 Redux-Saga사용자가 성공적으로 인증 할 때 기록 개체를 프로그래밍 방식으로 변경하는 데 사용 하기 때문에이 문제가 발생 했습니다.
React Router 문서에서 <Router> 구성 요소를 살펴보고 소품을 통해 자신의 기록 개체를 전달할 수 있음을 알 수 있습니다. 이것이 솔루션의 본질입니다. 우리React-Router 는 전역 모듈 에서 히스토리 오브젝트 를 제공합니다 .
단계 :
- 히스토리 npm 모듈 설치-
yarn add history또는npm install history --save -
레벨 폴더
history.js에 파일을 생성 하십시오App.js(이것이 내 환경 설정이었습니다)// src/history.js import createHistory from 'history/createBrowserHistory'; export default createHistory();` -
이 히스토리 오브젝트를 라우터 컴포넌트에 다음과 같이 추가하십시오.
// src/App.js import history from '../your/path/to/history.js;' <Router history={history}> // Route tags here </Router> -
바로 가져 와서 예전처럼 URL을 조정 하여 글로벌 역사 개체를 :
import history from '../your/path/to/history.js;' history.push('new/path/here/');
이제 모든 것이 동기화 상태를 유지해야하며 구성 요소 / 컨테이너를 통하지 않고 프로그래밍 방식으로 기록 개체를 설정하는 방법에 액세스 할 수 있습니다.
답변
TL; DR :
if (navigate) {
return <Redirect to="/" push={true} />
}
간단하고 선언적인 대답은 다음 <Redirect to={URL} push={boolean} />과 함께 사용해야합니다 .setState()
push : boolean- true 인 경우 경로 재 지정은 현재 항목을 바꾸는 대신 새 항목을 내역으로 푸시합니다.
import { Redirect } from 'react-router'
class FooBar extends React.Component {
state = {
navigate: false
}
render() {
const { navigate } = this.state
// here is the important part
if (navigate) {
return <Redirect to="/" push={true} />
}
// ^^^^^^^^^^^^^^^^^^^^^^^
return (
<div>
<button onClick={() => this.setState({ navigate: true })}>
Home
</button>
</div>
)
}
}
여기에 전체 예제가 있습니다 . 자세한 내용은 여기를 참조 하십시오 .
추신. 이 예에서는 ES7 + Property Initializer 를 사용 하여 상태를 초기화합니다. 관심이 있으시면 여기도 보십시오 .
답변
useHistory함수 구성 요소를 사용하는 경우 후크 사용
useHistory후크를 사용 하여 history인스턴스 를 얻을 수 있습니다 .
import { useHistory } from "react-router-dom";
const MyComponent = () => {
var history = useHistory();
return (
<button onClick={() => history.push("/about")}>
Click me
</button>
);
}
useHistory후크 당신이 탐색하는 데 사용할 수 있다는 것을 역사 인스턴스에 액세스 할 수 있습니다.
history페이지 구성 요소 내에서 속성 사용
React Router history는 페이지 구성 요소를 포함한 일부 속성을 주입 합니다.
class HomePage extends React.Component {
render() {
const { history } = this.props;
return (
<div>
<button onClick={() => history.push("/projects")}>
Projects
</button>
</div>
);
}
}
하위 withRouter속성을 감싸서 라우터 속성을 주입
withRouter래퍼는 라우터 속성을 구성 요소에 주입합니다. 예를 들어,이 랩퍼를 사용하여 라우터를 주입하여 사용자 메뉴에 배치 된 단추 구성 요소를 로그 아웃 할 수 있습니다.
import { withRouter } from "react-router";
const LogoutButton = withRouter(({ history }) => {
return (
<button onClick={() => history.push("/login")}>
Logout
</button>
);
});
export default LogoutButton;
답변
props를 사용하여 히스토리 오브젝트에 액세스 할 수도 있습니다. this.props.history.push('new_url')
답변
1 단계 : 가져올 항목이 하나뿐입니다.
import {Route} from 'react-router-dom';
2 단계 : 경로에서 기록을 전달합니다.
<Route
exact
path='/posts/add'
render={({history}) => (
<PostAdd history={history} />
)}
/>
3 단계 : 내역은 다음 구성 요소에서 소품의 일부로 승인되므로 간단하게 다음을 수행 할 수 있습니다.
this.props.history.push('/');
그것은 쉽고 강력했습니다.
