반응과 레벨 업:라우터 반응

이 튜토리얼은 브래드 서쪽으로 반응에 세 부분으로 시리즈의 첫 번째입니다. 브래드 저에게이 투구 할 때,그는 반응에서 시작하기에 튜토리얼의 좋은 금액이 있습니다 지적,하지만 거기에서 어디로 가야하는지에 대해 많이하지. 당신이 반응하는 새로운 브랜드 인 경우,나는이 소개 비디오를 시청하는 것이 좋습니다. 이 시리즈는 기본이 출발하는 곳을 선택합니다.

기사 시리즈:

  1. 라우터 반응(현재!)
  2. 콘테이너 성분
  3. 돌아오는

경고! 이 문서는 반응 라우팅에 대한보다 표준 선택이되었다 라우터 4,사전 반응 작성되었습니다. 당신은 확실히 읽어야 여기에 라우터 4 반응 다루는 새로운 기사가있다.

처음 학습했을 때,나는 단일 구성 요소를 만들어 돔에 렌더링하는 방법을 보여주는 많은 초보자 가이드(예:1,2,3,4)를 발견했습니다. 하지만 실제 단일 페이지 응용 프로그램(스파)과 같이 더 큰 그림에서 어떻게 반응하는지 파악하는 데 어려움을 겪었습니다. 이 시리즈는 많은 자료를 다루고 있기 때문에 절대 초보자 개념을 다루지 않습니다. 대신 적어도 하나의 구성 요소를 만들고 렌더링하는 방법을 이미 이해하고 있다는 가정부터 시작합니다.

그것은 가치가 무엇을 위해,여기에 초보자를 목표로 다른 훌륭한 가이드입니다:

  • 반응.그리고 다른 모든 것들과 어떻게 어울리나요?
  • 재검토(산업)모범 사례
  • 반응.

시리즈 코드

이 시리즈는 또한 깃허브에서 함께 플레이 할 수있는 몇 가지 코드와 함께 제공됩니다. 시리즈 전반에 걸쳐,우리는 사용자와 위젯 주위에 초점을 맞춘 기본 스파를 구축 할 수 있습니다.

간단 하 고 간단한 것 들을 유지 하려면이 시리즈의 예제는 반응 및 반응 라우터에서 검색 됩니다 가정 하 여 시작 됩니다. 따라서 아래의 즉각적인 예에서require()또는import가 표시되지 않습니다. 이 튜토리얼이 끝날 무렵,우리는 기 허브를위한 웹팩과 바벨을 소개 할 것입니다. 그 시점에서,그것은 모두 에스 6 입니다!

반응-라우터

반응은 프레임 워크가 아니라 라이브러리입니다. 따라서 응용 프로그램의 모든 요구 사항을 해결하지는 않습니다. 이 구성 요소를 생성하고 상태를 관리하기위한 시스템을 제공에 좋은 일을하지만,더 복잡한 스파를 만드는 것은 지원 캐스트가 필요합니다. 우리가 살펴 보겠습니다 첫 번째는 반응 라우터입니다.

이전에 프런트 엔드 라우터를 사용했다면 이러한 개념 중 많은 부분이 익숙 할 것입니다. 그러나 이전에 사용했던 다른 라우터와 달리 반응 라우터는 처음에는 조금 이상하게 보일 수 있습니다.

입문서로서,이것은 단일 구성 요소를 렌더링하는 것과 같습니다:

var Home = React.createClass({ render: function() { return (<h1>Welcome to the Home Page</h1>); }});ReactDOM.render(( <Home />), document.getElementById('root'));

반응 라우터를 사용하여Home구성 요소를 렌더링하는 방법은 다음과 같습니다:

...ReactDOM.render(( <Router> <Route path="/" component={Home} /> </Router>), document.getElementById('root'));

<Router><Route>은 서로 다른 두 가지입니다. 그들은 기술적으로 반응하는 구성 요소이지만 실제로 스스로 돔을 생성하지는 않습니다. <Router>자체가'root'에 렌더링되는 것처럼 보일 수 있지만 실제로는 응용 프로그램의 작동 방식에 대한 규칙을 정의하는 것입니다. 앞으로 이동,당신은 종종이 개념을 볼 수 있습니다: 구성 요소는 때때로 돔 자체를 만드는 것이 아니라 다른 구성 요소를 조정하기 위해 존재합니다.

이 예에서<Route>은 홈 페이지/을 방문하여Home구성 요소를'root'으로 렌더링하는 규칙을 정의합니다.

다중 경로

이전 예에서 단일 경로는 매우 간단합니다. 우리는 이미 라우터가 관여하지 않고Home구성 요소를 렌더링 할 수있는 능력을 가지고 있기 때문에 그것은 우리에게 많은 가치를 제공하지 않습니다.

리액트 라우터의 전원은 여러 경로를 사용하여 현재 활성 상태인 경로를 기반으로 렌더링해야 하는 구성 요소를 정의할 때 발생합니다.:

ReactDOM.render(( <Router> <Route path="/" component={Home} /> <Route path="/users" component={Users} /> <Route path="/widgets" component={Widgets} /> </Router>), document.getElementById('root'));

<Route>은 경로가 일치하는 경우 해당 구성 요소를 렌더링합니다. 이 세 가지 구성 요소 중 하나만 주어진 시간에'root'에 렌더링됩니다. 이 전략을 통해 라우터를 돔'root'에 한 번 탑재 한 다음 라우터가 구성 요소를 경로 변경과 함께 교체합니다.

또한 라우터가 서버에 요청하지 않고 경로를 전환 할 것이라는 점도 주목할 가치가 있으므로 각 구성 요소가 완전히 새로운 페이지가 될 수 있다고 상상해보십시오.

재사용 가능한 레이아웃

우리는 단일 페이지 응용 프로그램의 겸손한 시작을보기 시작했습니다. 그러나 여전히 실제 문제를 해결하지는 못합니다. 물론,우리는 세 가지 구성 요소를 전체 페이지로 구축 할 수 있지만 코드 재사용은 어떻습니까? 이 세 가지 구성 요소는 헤더 및 사이드 바와 같은 공통 자산을 공유 할 수 있습니다.

이 모형을 닮은 웹 앱을 만들고 있다고 상상해 봅시다.:

간단한 웹 사이트 모형.

이 모형을 다시 사용할 수있는 섹션으로 나눌 수있는 방법에 대해 생각하기 시작하면,당신은이 아이디어를 끝낼 수 있습니다:

당신은 섹션으로 간단한 웹 모형을 깰 수있는 방법.

중첩 가능한 구성 요소와 레이아웃을 생각하면 재사용 가능한 부품을 만들 수 있습니다.

갑자기,예술 부서는 앱이 사용자를 검색하기위한 페이지와 유사한 위젯을 검색하기위한 페이지가 필요하다는 것을 알 수 있습니다. 사용자 목록 및 위젯 목록 모두 자신의 검색 페이지에 대해 동일한”모양”을 필요로,아이디어는 별도의 구성 요소로 검색 레이아웃을 가지고하는 것은 이제 더 의미가 있습니다:

사용자 대신에,지금 위젯을 검색하지만,상위 섹션은 동일하게 유지됩니다.

검색 레이아웃은 이제 모든 종류의 검색 페이지에 대한 상위 템플릿이 될 수 있습니다. 일부 페이지는 검색 레이아웃이 필요할 수 있지만 다른 페이지는 검색 레이아웃없이 기본 레이아웃을 직접 사용할 수 있습니다:

분리 된 레이아웃.

이것은 일반적인 전략이며 템플릿 시스템을 사용했다면 아마도 매우 비슷한 작업을 수행했을 것입니다. 이 작업을 수행 할 수 있습니다. 시작 하려면,우리는 자바 스크립트를 고려 하지 않고 정적 할 거 야:

<div> <!-- Main Layout --> <div class="app"> <header class="primary-header"><header> <aside class="primary-aside"></aside> <main> <!-- Search Layout --> <div class="search"> <header class="search-header"></header> <div class="results"> <!-- User List --> <ul class="user-list"> <li>Dan</li> <li>Ryan</li> <li>Michael</li> </ul> </div> <div class="search-footer pagination"></div> </div> </main> </div></div>

‘root’요소는 자바스크립트가 시작되기 전에 초기 본문이 가지고 있는 유일한 요소이기 때문에 항상 존재한다는 것을 기억하십시오. 우리의 전체 반응 응용 프로그램이 그것에 탑재되기 때문에”루트”라는 단어가 적합합니다. 그러나 당신이 그것을 부르는 것에 대한”올바른 이름”이나 관습은 없습니다. 나는”루트”를 선택 했으므로 예제 전체에서 계속 사용할 것입니다. <body>요소에 직접 장착하는 것은 매우 권장되지 않습니다.

:

var MainLayout = React.createClass({ render: function() { // Note the `className` rather than `class` // `class` is a reserved word in JavaScript, so JSX uses `className` // Ultimately, it will render with a `class` in the DOM return ( <div className="app"> <header className="primary-header"><header> <aside className="primary-aside"></aside> <main> {this.props.children} </main> </div> ); }});var SearchLayout = React.createClass({ render: function() { return ( <div className="search"> <header className="search-header"></header> <div className="results"> {this.props.children} </div> <div className="search-footer pagination"></div> </div> ); }});var UserList = React.createClass({ render: function() { return ( <ul className="user-list"> <li>Dan</li> <li>Ryan</li> <li>Michael</li> </ul> ); }});

내가”레이아웃”과”구성 요소”라고 부르는 것 사이에 너무 산만 해지지 마십시오. 이 세 가지 모두 반응 구성 요소입니다. 나는 그들이 수행하는 역할이기 때문에 그 중 두 가지를”레이아웃”이라고 부르기로 선택합니다.

결국”중첩 경로”를 사용하여UserListSearchLayout안에 배치 한 다음MainLayout안에 배치합니다. 그러나 먼저UserList이 부모SearchLayout안에 배치되면 부모가this.props.children를 사용하여 위치를 결정합니다. 모든 구성 요소에는this.props.children가 소품으로 있지만 구성 요소가 중첩 된 경우에만 부모 구성 요소가이 소품을 자동으로 채워집니다. 상위 구성 요소가 아닌 구성 요소의 경우this.props.childrennull입니다.

중첩 경로

어떻게 이러한 구성 요소를 중첩시킬 수 있습니까? 라우터는 우리를 위해 그것을 할 때 우리가 둥지 경로:

ReactDOM.render(( <Router> <Route component={MainLayout}> <Route component={SearchLayout}> <Route path="users" component={UserList} /> </Route> </Route> </Router>), document.getElementById('root'));

구성 요소는 라우터가 경로를 중첩하는 방법에 따라 중첩됩니다. 사용자가/users경로를 방문하면 반응 라우터는UserList구성 요소를SearchLayout안에 배치 한 다음 모두MainLayout안에 배치합니다. /users을 방문한 최종 결과는'root'안에 배치 된 세 개의 중첩 된 구성 요소가 될 것입니다.

사용자가 홈 페이지 경로(/)를 방문하거나 위젯을 검색하려는 경우에 대한 규칙이 없습니다. 그 단순성을 위해 밖으로 남아 있지만,의 새로운 라우터에 넣어 보자 있었다:

ReactDOM.render(( <Router> <Route component={MainLayout}> <Route path="/" component={Home} /> <Route component={SearchLayout}> <Route path="users" component={UserList} /> <Route path="widgets" component={WidgetList} /> </Route> </Route> </Router>), document.getElementById('root'));

Route구성 요소가 하나의 태그(<Route />또는 두 개:<Route>...</Route>)로 작성 될 수 있다는 의미에서 규칙을 따른다는 것을 눈치 챘을 것입니다. 사용자 지정 구성 요소 및 일반 돔 노드를 포함한 모든 사용자 지정 구성 요소에 적용됩니다. 예를 들어,<div />는 유효하며 렌더링될 때<div></div>로 변환됩니다.

간결함을 위해WidgetListUserList과 비슷하다고 상상해보십시오.

<Route component={SearchLayout}>에는 이제 두 개의 자식 경로가 있으므로 사용자는/users또는/widgets를 방문 할 수 있으며 해당<Route>SearchLayout구성 요소 내부에 해당 구성 요소를로드합니다.

또한Home구성 요소가SearchLayout가 포함되지 않고MainLayout안에 직접 배치되는 방법을 확인하십시오. 당신은 아마 경로를 다시 정렬하여 레이아웃 및 구성 요소가 중첩되는 방법을 다시 정렬 쉽게 상상할 수있다.

인덱스 경로

반응 라우터는 매우 표현력이 뛰어나며 종종 동일한 작업을 수행하는 방법이 하나 이상 있습니다. 예를 들어 우리는 또한 다음과 같이 위의 라우터를 작성했을 수 있습니다:

ReactDOM.render(( <Router> <Route path="/" component={MainLayout}> <IndexRoute component={Home} /> <Route component={SearchLayout}> <Route path="users" component={UserList} /> <Route path="widgets" component={WidgetList} /> </Route> </Route> </Router>), document.getElementById('root'));

그 다른 모습에도 불구하고,그들은 모두 동일한 방식으로 작동.

선택적 경로 특성

때때로<Route>은 위의SearchLayout경로와 같이path가 없는component속성을 갖습니다. 다른 경우에는pathcomponent이없는<Route>이 필요할 수 있습니다. 이유를 보려면 다음 예제부터 시작하겠습니다:

<Route path="product/settings" component={ProductSettings} /><Route path="product/inventory" component={ProductInventory} /><Route path="product/orders" component={ProductOrders} />

path/product부분은 반복적입니다. 우리는 새로 세 경로를 포장하여 반복을 제거 할 수 있습니다<Route>:

<Route path="product"> <Route path="settings" component={ProductSettings} /> <Route path="inventory" component={ProductInventory} /> <Route path="orders" component={ProductOrders} /></Route>

다시 말하지만,반응 라우터는 표현력을 보여줍니다. 퀴즈:두 솔루션 모두에서 문제를 발견 했습니까? 현재 사용자가/product경로를 방문했을 때의 규칙은 없습니다.

이 문제를 해결하려면 다음을 추가 할 수 있습니다.IndexRoute:

<Route path="product"> <IndexRoute component={ProductProfile} /> <Route path="settings" component={ProductSettings} /> <Route path="inventory" component={ProductInventory} /> <Route path="orders" component={ProductOrders} /></Route>

사용<Link><a>

경로에 대한 앵커를 만들 때는<a href="">대신<Link to="">를 사용해야 합니다. 하지만 걱정하지 마세요,사용하는 경우<Link>구성 요소,반응 라우터는 궁극적으로 당신에게 돔에서 일반 앵커를 줄 것이다. <Link>를 사용하는 것은 반응 라우터가 라우팅 마법의 일부를 수행하는 데 필요합니다.

MainLayout에 링크(앵커)를 추가하겠습니다.:

var MainLayout = React.createClass({ render: function() { return ( <div className="app"> <header className="primary-header"></header> <aside className="primary-aside"> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/users">Users</Link></li> <li><Link to="/widgets">Widgets</Link></li> </ul> </aside> <main> {this.props.children} </main> </div> ); }});

<Link>구성 요소의 속성은 사용자가 만든 앵커로 전달됩니다. 그래서:

<Link to="/users" className="users">

돔이 될 것입니다:

<a href="/users" class="users">

외부 웹 사이트와 같은 비 라우터 경로에 대한 앵커를 작성해야하는 경우 평소와 같이 일반 앵커 태그를 사용하십시오. 자세한 내용은 인덱스 경로 및 링크에 대한 설명서를 참조하십시오.

활성 링크

<Link>구성 요소의 멋진 기능은 활성 상태 일 때 알 수있는 기능입니다:

<Link to="/users" activeClassName="active">Users</Link>

사용자가/users경로에 있으면 라우터는<Link>로 만들어진 일치하는 앵커를 찾고active클래스를 전환합니다. 이 기능에 대한 자세한 내용을 참조하십시오.

브라우저 기록

혼동을 방지하기 위해 지금까지 중요한 세부 사항을 남겼습니다. <Router>은 어떤 기록 추적 전략을 사용해야하는지 알아야합니다. 반응 라우터 문서는 다음과 같이 구현되는 브라우저 히스토리를 권장합니다:

var browserHistory = ReactRouter.browserHistory;ReactDOM.render(( <Router history={browserHistory}> ... </Router>), document.getElementById('root'));

이전 버전의 반응 라우터에서는history특성이 필요하지 않으며 기본값은 해시 히스토리를 사용하는 것입니다. 이 예제에서는 프론트엔드 스파 스타일 라우팅을 관리하는 데 사용되는 해시 기호(백본에서 기대할 수 있는 것과 유사)를 사용합니다.라우터.

hashHistory:

  • example.com
  • example.com/#/users?_k=ckuvup
  • example.com/#/widgets?_k=ckuvup

그 못생긴 쿼리 문자열은 무엇입니까?

browserHistory가 구현되면 경로가 더 유기적으로 보입니다:

  • example.com
  • example.com/users
  • 예.서버에서는 프런트 엔드에서browserHistory를 사용할 때 주의해야 할 점이 있습니다. 사용자가example.com에서 방문을 시작한 다음/users/widgets로 이동하면 리액트 라우터는 예상대로 이 시나리오를 처리합니다. 그러나 사용자가example.com/widgets를 브라우저에 직접 입력하여 방문을 시작하거나example.com/widgets에서 새로 고치면 브라우저는/widgets에 대해 서버에 적어도 하나 이상의 요청을 해야 합니다. 하지만 서버 측 라우터가없는 경우,이 제공 할 것입니다 404:
    사이트 조심하세요. 당신은 서버 측 라우터가 필요합니다.

    서버에서 404 문제를 해결하려면 리액트 라우터는 서버 쪽에서 와일드카드 라우터를 권장합니다. 이 전략을 사용하면 서버 측 경로가 호출 되더라도 서버는 항상 동일한 파일을 제공해야합니다. 리액트 라우터는 올바른 구성 요소를 로드할 수 있을 만큼 똑똑합니다.

    사용자는 이상한 것을 눈치 채지 못할 것입니다. 코드 예제에서 이 시리즈는”와일드카드 라우터”전략을 계속 사용하지만 서버 쪽 라우팅을 적절하게 처리하는 것은 사용자의 몫입니다.

    반응 라우터는 동형 방식으로 서버 측과 클라이언트 측 모두에서 사용할 수 있습니까? 물론 그것은 할 수 있지만,이 튜토리얼의 범위를 벗어나는 방법입니다.

    browserHistory

    로 리디렉션browserHistory객체는 단일 톤이므로 모든 파일에 포함시킬 수 있습니다. 코드에서 사용자를 수동으로 리디렉션해야 하는 경우push메서드를 사용하여 이를 수행할 수 있습니다:

    browserHistory.push('/some/path');

    경로 일치

    반응 라우터는 다른 라우터와 유사하게 경로 일치를 처리합니다.:

    <Route path="users/:userId" component={UserProfile} />

    이 경로는 사용자가users/로 시작하고 이후에 값이 있는 경로를 방문할 때 일치합니다. 그것은/users/1,/users/143또는 심지어/users/abc(스스로 검증해야합니다)와 일치합니다.

    반응 라우터는UserProfile에 대한 소품으로:userId의 값을 전달합니다. 이 소품은UserProfile내부의this.props.params.userId로 액세스됩니다.

    라우터 데모

    이 시점에서,우리는 데모를 표시 할 수있는 충분한 코드를 가지고있다.이 경우 펜은 라우터에 연결된 모든 라우터에 연결되어 있습니다.

    이 예에서 몇 가지 경로를 클릭하면 브라우저의 뒤로 및 앞으로 버튼이 라우터에서 작동한다는 것을 알 수 있습니다. 이것이 이러한history전략이 존재하는 주된 이유 중 하나입니다. 또한,당신이 방문하는 각 경로와 함께,서버에 대한 요청이 없다는 것을 명심하십시오. 그 얼마나 멋진?이 예제에서는 전역 변수(예:1746>

    )를 사용합니다. ReactRouter객체 안에는RouterRoute구성 요소와 같이 필요한 모든 종류의 것들이 있습니다. 그래서 우리는ReactRouter를 다음과 같이 사용할 수 있습니다:

    ReactDOM.render(( <ReactRouter.Router> <ReactRouter.Route ... /> </ReactRouter.Router>), document.getElementById('root'));

    여기서 우리는 모든 라우터 구성 요소에 부모 객체ReactRouter를 접두사로 붙여야합니다. 또는 다음과 같은 새로운 파괴 구문을 사용할 수 있습니다:

    var { Router, Route, IndexRoute, Link } = ReactRouter

    이것은ReactRouter의 일부를 일반 변수로”추출”하여 직접 액세스 할 수 있도록합니다.

    이제부터,이 시리즈의 예제들은 소멸,확산 연산자,수입/수출,그리고 아마도 다른 것들을 포함한 다양한 구문 구문을 사용할 것이다. 각 구문에 대한 간략한 설명이있을 것입니다.이 시리즈와 함께 제공되는 기트 허브에는 많은 설명이 있습니다.

    웹팩과 바벨 번들링

    앞서 언급한 바와 같이,이 시리즈에는 기트허브 리포지토리가 함께 제공되므로 코드를 실험할 수 있습니다. 그것은 실제 스파의 자질과 유사하기 때문에,그것은 웹팩과 바벨 같은 도구를 사용합니다.

    • 웹팩은 여러 자바스크립트 파일을 브라우저에 대해 하나의 파일로 묶습니다.대부분의 브라우저는 아직 모든 코드를 이해하지 못하기 때문입니다. 이 문서의 나이로,브라우저는 에스 6 을 지원하고 바벨이 필요하지 않을 수 있습니다.

    아직 이러한 도구를 사용하여 너무 편안하지 않은 경우,걱정하지 마세요,예제 코드는 반응에 집중할 수 있도록 이미 모든 설정이 있습니다. 그러나 예제 코드를 검토해야합니다 README.md 추가 워크플로 문서 파일.

    더 이상 사용되지 않는 구문

    구글에서 리액트 라우터에 대한 정보를 검색하면 리액트 라우터가 1.0 이전 릴리스에있을 때 작성된 많은 기사 또는 스택 오버 플로우 페이지 중 하나에 착륙 할 수 있습니다. 사전 1 에서 많은 기능.0 릴리스는 이제 더 이상 사용되지 않습니다. 여기에 짧은 목록입니다:

    • <Route name="" /> 더 이상 사용되지 않습니다. 대신<Route path="" />을 사용하십시오.
    • <Route handler="" />은 더 이상 사용되지 않습니다. 대신<Route component="" />를 사용하십시오.
    • <NotFoundRoute />는 더 이상 사용되지 않습니다. 참조 대안
    • <RouteHandler />은 더 이상 사용되지 않습니다.
    • willTransitionTo은 더 이상 사용되지 않습니다. 자세한 내용은 참조하십시오. “위치”는 이제”기록”이라고합니다.

    1.0.0 및 2.0.0 에 대한 전체 목록을 참조하십시오

    요약

    아직 표시되지 않은 반응 라우터에 더 많은 기능이 있습니다. 반응 라우터의 제작자는 또한 반응 라우터에 대한 단계별 자습서를 만들고이 반응을 체크 아웃했습니다.반응 라우터가 생성 된 방법에 대한 비디오.

    린 낸드 토닉

    작품에 대한 린 피셔 특별 감사 기사 시리즈:

    1. 라우터 반응(현재!)
    2. 컨테이너 구성 요소
    3. 돌아 오는

답글 남기기

이메일 주소는 공개되지 않습니다.