ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Router의 Link, Switch, history
    React 2022. 3. 15. 13:45

    앞과 같이 상세페이지를 만들었다.

    <Route path="/detail">
          <div className="container">
            <div className="row">
              <div className="col-md-6">
                <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" />
              </div>
              <div className="col-md-6 mt-4">
                <h4 className="pt-5">상품명</h4>
                <p>상품설명</p>
                <p>120000원</p>
                <button className="btn btn-danger">주문하기</button> 
              </div>
            </div>
          </div> 
    </Route>

    이렇게 긴 상세페이지를 component화 해서 함수로 만든 후, 한단어로 쓸 수 있다.

    function Detail() {
    	return (
          <div className="container">
            <div className="row">
              <div className="col-md-6">
                <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" />
              </div>
              <div className="col-md-6 mt-4">
                <h4 className="pt-5">상품명</h4>
                <p>상품설명</p>
                <p>120000원</p>
                <button className="btn btn-danger">주문하기</button> 
              </div>
            </div>
          </div>
        )
    }
    
    //function App밖에 이렇게 만들고, 상세페이지에 Detail() 쓰면 된다.

    그리고 다른 파일로 빼서 만들 수도 있다. 파일 이름을 Detail.js로 만든 후, 컴포넌트 파일을 만들 땐 import React를 해와야 한다.

    import React, {useState} from 'react';
    
    function Detail() {
    	return (
          <div className="container">
            <div className="row">
              <div className="col-md-6">
                <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" />
              </div>
              <div className="col-md-6 mt-4">
                <h4 className="pt-5">상품명</h4>
                <p>상품설명</p>
                <p>120000원</p>
                <button className="btn btn-danger">주문하기</button> 
              </div>
            </div>
          </div>
        )
    };
    
    export default Detail;

    이렇게 export를 써주고 app.js에

    import Detail from './Detail';
    
    function App() {
    	return (
        	<Route path="/detail">
            	<Detail />
          	</Route>
        )
    }

    이렇게 간단하게 줄일 수 있다. 이런 과정을 모듈화라고 부른다.

     

    이번엔, 주소창에 /detail을 입력해서 이동하지 말고, 버튼을 누르면 메인페이지와 상세페이지로 가는 버튼을 만들어보자.

    <Nav.Link ><Link to="/">Home</Link></Nav.Link>
    <Nav.Link ><Link to="/detail">Detail</Link></Nav.Link>
    //Nav.Link와 Link가 겹치면 a태그가 중복된걸로 감지해 콘솔창에 에러가 뜬다
    //이럴땐 <Nav.Link as={Link} to="/detail">Detail</Nav.Link>
    //이렇게 부트스트랩의 link로 축약해주면 된다. 그리고 as={Link}를 써서 Link의 역할을 하게하면 된다.

    이렇게 Link태그에 to를 이용해 적어주면 Home을 누르면 / (메인페이지)로 Detail을 누르면 /detail(상세페이지)로 이동한다. 물론 상단에 import {Link} from 'react-router-dom';을 작성해야 한다. 

     

    그리고 Link를 이용하지 말고, 페이지를 버튼으로 이동하는 방법도 있다. 

    먼저, detail페이지에 뒤로가기 버튼을 만들고 history훅을 이용한다.

    그리고 따로 만들어 놓은 detail.js 파일에

    import React, {useState} from 'react';
    import { useHistory } from 'react-router-dom';
    
    function Detail() {
    
        let history = useHistory(); //방문기록 등을 저장해놓는 object
    
    	return (
          <div className="container">
            <div className="row">
              <div className="col-md-6">
                <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" />
              </div>
              <div className="col-md-6 mt-4">
                <h4 className="pt-5">상품명</h4>
                <p>상품설명</p>
                <p>120000원</p>
                <button className="btn btn-danger">주문하기</button> 
                <button className="btn btn-danger" onClick={ () => { 
                	history.goBack();//뒤로가는 함수
                    //history.push('경로')이렇게하면 특정경로로 이동시킴
                } }>뒤로가기</button> 
              </div>
            </div>
          </div>
        )
    }
    
    export default Detail;

    이렇게 상단에 useHistory를 import해주고 let history = useHistory();를 적어주면 훅을 사용할 수 있다. 그러고 버튼을 onClick하면 history훅을 이용해 history.goBack();함수를 작성해주면 뒤로 갈 수 있다.

     

    마지막으로, switch에 대해 알아보자

    리액트는

    <Route exact path="/"> 
          <div className="jumbotron">
              <h1>20% Season Off</h1>
              <p>fdsfsdf</p>
              <button className="btn btn-primary">Learn more</button>
          </div>
    
          <div className="container">
            <div className="row">
                {
                  shoes.map( (a,i) => {
                    return <ShopList shoes={shoes[i]} i={i} key={i}/>
                  })
                }
            </div>
          </div>
    </Route>
    <Route path="/detail">
          <Detail />
    </Route>
    <Route path="/:id">
          <div>아무거나 적으면 이거보여줌</div>
    </Route>

    이렇게 경로가 / , /detail , /:id( /:id는 /뒤에 아무문자나 오면 여기로 보내라 라는 뜻 ) 세개일 때, /detail에 들어가면 

    path="/:id"의 라우터가 보여진다. 이것을 방지하기 위해 switch 컴포넌트를 사용한다. 여러개가 맞아도 하나만 보여주세요 라는 뜻이고

    <Switch>
          <Route exact path="/"> 
            //html덩어리
          </Route>
          <Route path="/detail">
            <Detail />
          </Route>
          <Route path="/:id">
            <div>아무거나 적으면 이거보여줌</div>
          </Route>
    </Switch>

    이런 식으로, Route들을 감싸준다. 즉, 중복매칭을 허용하지 않는다. 이러면 exact를 쓰지 않고도 해결가능하다.

    순서를 바꿔주면 되는데, /detail처럼 /뒤에 더 주소가 있는것을 상단에 놓고, 다음에 /:id 그리고 마지막에 /를 놓으면 exact를 쓰지 않아도 잘 작동한다. 

    'React' 카테고리의 다른 글

    styled-components  (0) 2022.03.17
    여러 페이지 만들기 router활용  (0) 2022.03.16
    Router의 기본  (0) 2022.03.15
    import / export  (0) 2022.03.14
    React의 bootstrap과 img관리  (0) 2022.03.14

    댓글

Designed by Tistory.