[モダン反応]5枚ルーター


1.プロジェクトの準備と基本的な使用方法


プロジェクトへのルータの適用


ルータのインデックスを適用します.jsでは、BrowserRouterというコンポーネントを使用して実装される.

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom'; // * BrowserRouter 불러오기
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

// * App 을 BrowserRouter 로 감싸기!
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

serviceWorker.unregister();

ページの作成


src/Home.js

import React from 'react';

const Home = () => {
  return (
    <div>
      <h1></h1>
      <p>이곳은 홈이에요. 가장 먼저 보여지는 페이지죠.</p>
    </div>
  );
};

export default Home;

src/About.js

import React from 'react';

const About = () => {
  return (
    <div>
      <h1>소개</h1>
      <p>이 프로젝트는 리액트 라우터 기초를 실습해보는 예제 프로젝트랍니다.</p>
    </div>
  );
};

export default About;

Route:構成部品を特定のアドレスに接続する


ユーザーが要求したアドレスに基づいて、他のコンポーネントが表示されます.この操作を行うには、Routeという要素を使用します.
<Route path="주소규칙" component={보여주고싶은 컴포넌트}>

src/App.js


exactというpropsをtrueに設定すると、パスが完全に同じ場合にのみ構成部品が表示されます.
import React from 'react';
import { Route } from 'react-router-dom';
import About from './About';
import Home from './Home';

const App = () => {
  return (
    <div>
      <Route path="/" exact={true} component={Home} />
      <Route path="/about" component={About} />
    </div>
  );
};

export default App;

リンク:クリックすると他のアドレスに移動


リンクコンポーネントは、クリックして別のアドレスに移動するコンポーネントです.反応ルータを使用する場合は、通常<a href="...">...</a>ラベルを使用しないでください.もしそうであれば、onClickにe.preventDefault()を呼び出し、アドレスをJavaScriptに変換する必要があります.
逆に、Linkという名前のコンポーネントを使用する必要があります.これは、aラベルの基本プロパティがページを移動し、ページが直接再ロードされるためです.これにより、リアクションアプリケーションが携帯する状態も初期化され、レンダリングされたコンポーネントもすべて消え、再レンダリングされます.リンクコンポーネントは、ページを再ロードせずにHTML5 History APIを使用してブラウザアドレスを変更します.

src/App.js

import React from 'react';
import { Route, Link } from 'react-router-dom';
import About from './About';
import Home from './Home';

const App = () => {
  return (
    <div>
      <ul>
        <li>
          <Link to="/"></Link>
        </li>
        <li>
          <Link to="/about">소개</Link>
        </li>
      </ul>
      <hr />
      <Route path="/" exact={true} component={Home} />
      <Route path="/about" component={About} />
    </div>
  );
};

export default App;

2.パラメータとクエリー


ページアドレスを定義するときに、フローティング値を渡す必要がある場合があります.これはパラメータとクエリーに分けられます.
파라미터: /profiles/sshin
쿼리: /about?details=true
守らなければならないルールはありませんが、一般的には、
  • パラメータ:特定のidまたは名前を使用して検索
  • クエリー:キーワードを検索または要求した場合、必要なオプション
  • を転送
    使用します.

    URL Params


    Profileページでパラメータを使用します./profile/sshinこのようにして後でユーザ名を追加する場合は、これをパラメータとして入力する.

    src/Profile.js


    パリメートルを受け取った場合は、matchのparams値を参照してください.
    matchオブジェクトには、Routeコンポーネントで定義されたルールと現在のアドレスがどのように一致するかに関する情報が含まれます.
    import React from 'react';
    
    // 프로필에서 사용 할 데이터
    const profileData = {
      sshin: {
        name: '신성우',
        description:
          'Frontend Engineer'
      },
      gildong: {
        name: '홍길동',
        description: '전래동화의 주인공'
      }
    };
    
    const Profile = ({ match }) => {
      // 파라미터를 받아올 땐 match 안에 들어있는 params 값을 참조합니다.
      const { username } = match.params;
      const profile = profileData[username];
      if (!profile) {
        return <div>존재하지 않는 유저입니다.</div>;
      }
      return (
        <div>
          <h3>
            {username}({profile.name})
          </h3>
          <p>{profile.description}</p>
        </div>
      );
    };
    
    export default Profile;

    src/App.js


    次に、アプリケーションにProfileを適用します.pathルールに/profile/:usernameを追加すると、usernameに対応する値がパラメータとして使用され、profileコンポーネントのmatch propsで渡すことができます.
    import React from 'react';
    import { Route, Link } from 'react-router-dom';
    import About from './About';
    import Home from './Home';
    import Profile from './Profile';
    
    const App = () => {
      return (
        <div>
          <ul>
            <li>
              <Link to="/"></Link>
            </li>
            <li>
              <Link to="/about">소개</Link>
            </li>
          </ul>
          <hr />
          <Route path="/" exact={true} component={Home} />
          <Route path="/about" component={About} />
          <Route path="/profiles/:username" component={Profile} />
            // username에 해당하는 값을 파라미터로 넣어주어서
            // Profile 컴포넌트에서 match props를 통해 
            // 전달받을 수 있게 된다!!!
        </div>
      );
    };
    
    export default App;

    Query


    今回はAboutページからクエリーを取得します.クエリーは、propsとしてルーティングコンポーネントに渡されるlocationオブジェクトの検索値から取得できます.locationオブジェクトは、現在のアプリケーションが所有するアドレスに関する情報を保持します.
    {
      key: 'ac3df4', // not with HashHistory!
      pathname: '/somewhere'
      search: '?some=search-string', // <-
      hash: '#howdy',
      state: {
        [userDefined]: true
      }
    }
    search値は文字列形式で存在するため、オブジェクト形式に変換するには自分で行う必要があります.このタスクは、qsというライブラリを使用して簡単に実行できます.

    src/About.js


    Aboutエレメントから検索値のdetail値を取得し、trueとして実装すると他の情報が表示されます.
    import React from 'react';
    import qs from 'qs'; // 1. import
    
    const About = ({ location }) => {
      const query = qs.parse(location.search, {
        ignoreQueryPrefix: true
      }); // 2. query 파싱
      const detail = query.detail === 'true';
    	// 3. detail 값 비교!
      // 쿼리의 파싱결과값은 문자열입니다. -> 문자열간 비교
      
      // localhost:3000/about?detail=true
    
      return (
        <div>
          <h1>소개</h1>
          <p>이 프로젝트는 리액트 라우터 기초를 실습해보는 예제 프로젝트랍니다.</p>
          {detail && <p>추가적인 정보가 어쩌고 저쩌고..</p>}
        </div>
      );
    };
    
    export default About;

    3.サブルート


    サブルーティングは、ルーティング内部にルーティングを作成することを意味します.構成部品を作成し、Route構成部品を追加するだけです.

    サブルーティングの作成


    src/Profiles.js


    第1のルーティング要素は、componentではなくrenderを使用する.ここでは、構成部品ではなくJSX自体をレンダリングできます.JSXをレンダリングするため、親領域にpropsまたは他の値を渡す必要がある場合は、それを渡すことができます.
    import React from 'react';
    import { Link, Route } from 'react-router-dom';
    import Profile from './Profile';
    
    const Profiles = () => {
      return (
        <div>
          <h3>유저 목록:</h3>
          <ul>
            <li>
              <Link to="/profiles/sshin">sshin</Link>
            </li>
            <li>
              <Link to="/profiles/gildong">gildong</Link>
            </li>
          </ul>
    
          <Route
            path="/profiles"
            exact
            render={() => <div>유저를 선택해주세요.</div>}
          />
          <Route path="/profiles/:username" component={Profile} />
        </div>
      );
    };
    
    export default Profiles;

    src/App.js


    Profilesのリンクとルーティングを作成します.
    import React from 'react';
    import { Route, Link } from 'react-router-dom';
    import About from './About';
    import Home from './Home';
    import Profiles from './Profiles';
    
    const App = () => {
      return (
        <div>
          <ul>
            <li>
              <Link to="/"></Link>
            </li>
            <li>
              <Link to="/about">소개</Link>
            </li>
            <li>
              <Link to="/profiles">프로필 목록</Link>
            </li>
          </ul>
          <hr />
          <Route path="/" exact={true} component={Home} />
          <Route path="/about" component={About} />
          <Route path="/profiles" component={Profiles} />
        </div>
      );
    };
    
    export default App;
    サービスが特定のルーティング内にタブを作成する場合は、単純なステータス管理ではなくサブルーティングとして管理することを推奨します.これは、setStateを作成する必要がなく、リンクで簡単に他の場所から入ることができ、今後の検索エンジンのスクロールを考慮すると、検索エンジンロボットはより多くのデータを収集することができるからです.

    4.反応ルータ付加機能


    履歴オブジェクト


    historyオブジェクトは、ルーティングとして使用されるコンポーネントmatch、locationに渡されるpropsの1つである.このオブジェクトを使用すると、構成部品内で実装されている方法のルータに直接アクセスできます.-後退、特定経路への移動、離脱防止など.historyオブジェクトを使用すると、条件付きで他の場所に移動したり、メッセージボックスで離脱を阻止したりすることができます.

    src/HistorySample.js

    import React, { useEffect } from 'react';
    
    function HistorySample({ history }) {
      const goBack = () => {
        history.goBack();
      };
    
      const goHome = () => {
        history.push('/');
      };
    
      useEffect(() => {
        console.log(history);
        const unblock = history.block('정말 떠나실건가요?');
        return () => {
          unblock();
        };
      }, [history]);
    
      return (
        <div>
          <button onClick={goBack}>뒤로가기</button>
          <button onClick={goHome}>홈으로</button>
        </div>
      );
    }
    
    export default HistorySample;

    src/App.js

    import React from 'react';
    import { Route, Link } from 'react-router-dom';
    import About from './About';
    import Home from './Home';
    import Profiles from './Profiles';
    import HistorySample from './HistorySample';
    
    const App = () => {
      return (
        <div>
          <ul>
            <li>
              <Link to="/"></Link>
            </li>
            <li>
              <Link to="/about">소개</Link>
            </li>
            <li>
              <Link to="/profiles">프로필 목록</Link>
            </li>
            <li>
              <Link to="/history">예제</Link>
            </li>
          </ul>
          <hr />
          <Route path="/" exact={true} component={Home} />
          <Route path="/about" component={About} />
          <Route path="/profiles" component={Profiles} />
          <Route path="/history" component={HistorySample} />
        </div>
      );
    };
    
    export default App;

    withRouter HoC


    withRouterHocは、非ルーティング構成部品でmatch/location/historyを使用するために使用されます.
    親構成部品標準の一致値をwithRouterを使用して渡します.

    src/WithRouterSample.js

    import React from 'react';
    import { withRouter } from 'react-router-dom';
    const WithRouterSample = ({ location, match, history }) => {
      return (
        <div>
          <h4>location</h4>
          <textarea value={JSON.stringify(location, null, 2)} readOnly />
          <h4>match</h4>
          <textarea value={JSON.stringify(match, null, 2)} readOnly />
          <button onClick={() => history.push('/')}>홈으로</button>
        </div>
      );
    };
    
    export default withRouter(WithRouterSample);

    src/Profiles.js

    import React from 'react';
    import { Link, Route } from 'react-router-dom';
    import Profile from './Profile';
    import WithRouterSample from './WithRouterSample';
    
    const Profiles = () => {
      return (
        <div>
          <h3>유저 목록:</h3>
          <ul>
            <li>
              <Link to="/profiles/sshin">sshin</Link>
            </li>
            <li>
              <Link to="/profiles/gildong">gildong</Link>
            </li>
          </ul>
    
          <Route
            path="/profiles"
            exact
            render={() => <div>유저를 선택해주세요.</div>}
          />
          <Route path="/profiles/:username" component={Profile} />
          <WithRouterSample />
        </div>
      );
    };
    
    export default Profiles;

    Switch


    スイッチは複数のルーティングを囲み、1つのルールが一致するルーティングのみをレンダリングします.Switchを使用すると、一致しないときに表示されるNot Foundページも実現できます.
    import React from 'react';
    import { Switch, Route, Link } from 'react-router-dom';
    import About from './About';
    import Home from './Home';
    import Profiles from './Profiles';
    import HistorySample from './HistorySample';
    
    const App = () => {
      return (
        <div>
          <ul>
            <li>
              <Link to="/"></Link>
            </li>
            <li>
              <Link to="/about">소개</Link>
            </li>
            <li>
              <Link to="/profiles">프로필 목록</Link>
            </li>
            <li>
              <Link to="/history">예제</Link>
            </li>
          </ul>
          <hr />
          <Switch> // <-
            <Route path="/" exact={true} component={Home} />
            <Route path="/about" component={About} />
            <Route path="/profiles" component={Profiles} />
            <Route path="/history" component={HistorySample} />
            <Route
              // path 를 따로 정의하지 않으면 모든 상황에 렌더링됨
              render={({ location }) => (
                <div>
                  <h2>이 페이지는 존재하지 않습니다:</h2>
                  <p>{location.pathname}</p>
                </div>
              )}
            />
          </Switch>
        </div>
      );
    };
    
    export default App;

    NavLink


    NavLinkはLinkと似ています.現在のパスがLinkで使用されているパスと一致する場合、特定のスタイルまたはクラスのコンポーネントを適用できます.

    src/Profiles.js

    import React from 'react';
    import { Route, NavLink } from 'react-router-dom';
    import Profile from './Profile';
    import WithRouterSample from './WithRouterSample';
    
    const Profiles = () => {
      return (
        <div>
          <h3>유저 목록:</h3>
          <ul>
            <li>
              <NavLink
                to="/profiles/sshin"
                activeStyle={{ background: 'black', color: 'white' }}
              >
                sshin
              </NavLink>
            </li>
            <li>
              <NavLink
                to="/profiles/gildong"
                activeStyle={{ background: 'black', color: 'white' }}
              >
                gildong
              </NavLink>
            </li>
          </ul>
    
          <Route
            path="/profiles"
            exact
            render={() => <div>유저를 선택해주세요.</div>}
          />
          <Route path="/profiles/:username" component={Profile} />
          <WithRouterSample />
        </div>
      );
    };
    
    export default Profiles;

    その他

  • Redirect:リダイレクトページのコンポーネント
  • Prompt:以前に使用された歴史.ブロックの構成部品バージョン
  • Route Config:配列/オブジェクトを使用してルーティングを定義し、JSX形式でルーティングを宣言するのではなく、ルーティングを定義します
  • Memory Router実際にはアドレスのルータは存在しない.反応帳やimbeddywebアプリケーションで使用すると便利です.
  • 公式マニュアル