[React] chap.2

 

 

 

기본 세팅

* yarn

- 구글에 yarn 1.22 검색 (2 버전은 아직 불안정)

https://classic.yarnpkg.com/en/docs/install#windows-stable

 

Yarn

Fast, reliable, and secure dependency management.

classic.yarnpkg.com

npm install --global yarn // 설치
yarn --version // 버전 체크
yarn start // 서버 시작

 

 

 

* Bootstrap

https://react-bootstrap.github.io/getting-started/introduction

 

React-Bootstrap

The most popular front-end framework, rebuilt for React.

react-bootstrap.github.io

npm install react-bootstrap bootstrap@5.1.3 // 리액트 부트스트랩 설치
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" />

css 링크도 받아온다.

 

 

 

폴더 경로

* src: (./ img, js, css, html 등의 아무파일)

* public: 17버전 이상 부터 풀 경로를 사용해야 함.

 

 

 

React Router
* npm
npm install react-router-dom@5

* yarn
yarn add react-router-dom@5

터미널 세팅

 

import 어쩌구 많은곳;

import { BrowserRouter } from 'react-router-dom';
// import {HashRouter} from 'react-router-dom';

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
    <!-- {/* <HashRouter> */} -->
    <App />
    <!-- {/* </HashRouter> */} -->
    </BrowserRouter>
  </React.StrictMode>
  document.getElementById('root')
);

: index.js

 

HashRouter는 서버가 없고 리액트로 라우팅만 담당할 시에 잘못된 페이지를 서버에 요청할 경우 '#'을 붙여줘서 안정성 있게 사용할 수 있다.

 

 

* Route

import 많은 곳;
import { Link, Route, Switch } from 'react-router-dom';

function App(){
  return (
    <div>
      HTML 잔뜩있는 곳 

      <Route exact path="/">
        <div>메인 페이지입니다</div>
      </Route>

      <Route path="/detail">
        <div>상세페이지인데요</div>
      </Route>
      
      <!-- {/* <Route path="/어쩌구" component={Modal}></Route> */} -->
    </div>
  )
}

path: 해당 라우팅 페이지의 경로를 지정한다.

exact: 상위 경로의 내용이 밑에 하위경로까지 전달되는 것을 막는다. 

component: 해당 경로의 내용을 컴포넌트 단위로 가져와서 사용할 수 있다.

 

 

 

* Link

function App(){
  return (
    <div>
      <Navbar>
         <Nav.Link> <Link to="/">Home</Link> </Nav.Link>
         <Nav.Link> <Link to="/detail">Detail</Link> </Nav.Link>
      </Navbar> 
      <나머지HTML/>
    </div>
  )
}

to: Link 태그 안에서 to 속성을 통해 경로를 지정하면 a 태그와 유사하게 페이지 이동을 할 수 있다.

 

 

- 페이지 이동함수

import React from 'react';
import { useHistory } from 'react-router-dom';

function Detail(){
  
  let history = useHistory();
  return (
    <button className="btn btn-danger" onClick={ () => {
       // history.push('/');
        history.goBack();
     } }>뒤로가기</button> 
  )
};

export default Detail

router의 기능중에 useHistory라는 훅 기능을 사용하면 페이지의 이동 내역과 다른 함수가 있기 때문에 해당 페이지 이동을 할 수 있다. history 라는 object의 goBack함수를 사용하면 뒤로가기 기능을 구현할 수 있다. 다른페이지로 이동하려면 push()함수를 사용하면 된다.

 

 

* Switch

function App(){
  return (
    <div>
      <나머지HTML/>
      <Switch>
        <Route exact path="/">
          어쩌구
        </Route>
        <Route path="/detail">
          <Detail/>
        </Route>
      <Route path="/:id"> <!-- URL 파라미터 -->
          <div>새로 만든 route입니다</div>
        </Route>
      </Switch>
    </div>
  )
}

: 매치되는 Router를 전부 보여주지않고 한번에 하나만 볼때 사용

 

여러개의 Route가 매칭 되어 있을 때 같은 내용이 출력되었는데 위처럼 Switch로 묶으면 맨위의 Route 하나만 보여준다. (exact랑 비슷)

 

 

* URL 파라미터

URL뒤에 어떤 문자가 오던간에 해당 URL로 이동할 수 있다. (파라미터처럼 적용할 수 있음)

function App(){
  return (
    <div>
      <나머지HTML/>
        <Route path="/detail/:id"> <!-- URL 파라미터 -->
          <Detail shoes={shoes}/>
        </Route>
    </div>
  )
}

** 데이터는 항상 위에서 아래로 흐르는게 좋다 (상위에서 하위로)

 

import React from 'react';
import { useHistory, useParams } from 'react-router-dom';

function Detail(props){

  let { id } = useParams(); // destructuring
  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">{props.shoes[:id자리에 있던숫자].title}</h4>
          <p>{props.shoes[:id자리에 있던숫자].content}</p>
          <p>{props.shoes[:id자리에 있던숫자].price}원</p>
          <button className="btn btn-danger">주문하기</button> 
        </div>
      </div>
  </div>  
  )
};

export default Detail

useParams(): 해당 함수는 현재 URL에 적힌 모든 파라미터를 object 자료로 저장해주는 함수이다.

 

 

 

 

 

styled-components

컴포넌트를 제작할 때, 스타일을 바로 입혀서 제작하는 방식. 컴포넌트가 많아졌을 때, css의 중복을 피하거나 css의 너무 길어질 때 사용한다.

// npm
npm install styled-components

// yarn
yarn add styled-components

 

import styled from 'styled-components'

: styled 임포트

 

import React, { useState } from 'react';
import styled from 'styled-components';

let 박스 = styled.div`
  padding : 20px;
`;
let 제목 = styled.h4`
  font-size : 25px;
  color : ${ props => props.색상 };
`;

function Detail(){
  return (
    <div>
      <HTML 많은 곳/>
      <박스>
        <제목 색상="blue">안녕하세요1</제목>
        <제목 색상={'red'}>안녕하세요2</제목>
      </박스>
    </div>
  )
}

컴포넌트를 제작할 때 미리 스타일을 주입해서 만들 수 있다.

  • styled.태그 형식으로 사용한다.
  • 태그 뒤에 `` (backtick) 기호를 사용해서 기본 스타일링을 한다.
  • 변수로 저장해서 원하는 자리에 사용할 수 있다.

 

 

- props 추가하기

color : ${ props => props.색상 };

만들었던 스타일의 속성 값으로 변수처럼 받아와서 사용할 수 있다. 위 처럼 콜백함수 형식으로 비슷한 형태의 스타일을 조금씩 다르게 정의 할 수 있다.

 

 

 

React SASS
// npm
npm install node-sass

// yarn
yarn add node-sass

해당 라이브러리가 scss 파일을 css 파일로 자동변환 해준다.

 

import './Detail.scss';

라이브러리를 설치했다면 scss 파일은 scss확장자로 import하면 된다.

 

 

- SASS

  • 1. 변수 사용
$메인칼라 : #ff0000;
  • 2. @import
@import './어쩌구.css'; /* css나 scss파일 간 import */
  • 3. nesting
div.container {
  h4 {
    color : blue;
  }
  p {
    color : green;
  }
}
  • 4. @extends
.my-alert {
  background : #eeeeee;
  padding : 15px;
  border-radius : 5px;
  max-width : 500px;
  width : 100%;
  margin : auto;
}
.my-alert2 {
  @extend .my-alert; /* 클래스간 extend*/
  background : yellow;
}

.my-alert p {
  margin-bottom : 0;
}
  • 5. @mixin / @include
@mixin 함수() {
  background : #eeeeee;
  padding : 15px;
  border-radius : 5px;
  max-width : 500px;
  width : 100%;
  margin : auto;
}
.my-alert {
  @include 함수()
}

.my-alert p {
  margin-bottom : 0;
}

 

 

 

Lifecycle Hook & useEffect

컴포넌트의 주기 중간중간에 Hook을 사용할 수 있다.

 

- Lifecycle Hook

class Detail2 extends React.Component {
  componentDidMount(){
    //Detail2 컴포넌트가 Mount 되고나서 실행할 코드
  }
  componentWillUnmount(){
    //Detail2 컴포넌트가 Unmount 되기전에 실행할 코드
  }
}

 

 

- useEffect Hook

import React, {useState, useEffect} from 'react';

function Detail(){

  useEffect(()=>{
    //코드를 적습니다 여기    
    
    return function 어쩌구(){ 
    	// unmount될 때 실행할 코드 
    }       
  });
  
  // useEffect(() => {});
  // useEffect(() => {}); 
  // ... 여러개 사용 가능  
  
  return (
    <HTML많은곳/>
  )
}

 

 

* useEffect 추가 기능 및 특징

useEffect는 해당하는 컴포넌트가 실행됐을 때, 사라질 때 기능을 추가 할 수 있는데, 그렇게 되면 useState에 등록된 값이 바뀔때마다 재렌더링 되어 원치 동작이 계속 일어날 수 있다.

 

useEffect(()=>{
   let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
}, []); // 초기 한번 실행빼고 다시 실행 안하기

useEffect 뒤에 빈 배열을 두면 초기 실행 한번 후 안할 수 있다.

 

useEffect(()=>{
   let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
}, [ alert ]); // alert라는 useState가 변경될 때만 실행

또, useEffect 뒤의 배열에 해당하는 useState 값을 넣으면 그 값이 변경 되어 재렌더링 될때 다시 실행한다. (배열 형식이라 콤마를 통해 여러개 넣을 수 있다)

 

 

- setTimeout

useEffect(()=>{
  let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);

  return ()=>{ clearTimeout(타이머) }
}, []);

추가적으로 useEffect의 return은 해당 컴포넌트가 사라질 때 동작하게 되는데, setTimeout 함수를 썼으면 해제하는 clearTimeout 함수로 해제하는게 버그에 대해 안전하다.

 

 

 

Ajax

서버에 새로고침없이 요청을 할 수 있게 도와주는 일종의 자바스크립트 코드 (GET, POST)

  • jQuery Ajax
  • react axios
  • javascript fetch

 

 

* axios

// npm
npm install axios

// yarn
yarn add axios

라이브러리 다운

 

 

- get 요청

import axios from 'axios';

function App(){
  
  return (
    <HTML많은곳/>
    <button className="btn btn-primary" onClick={()=>{

      <!-- fetch('https://codingapple1.github.io/shop/data2.json') -->
      <!-- .then() -->

      axios.get('요청 url')
      .then(()=>{ 요청성공시실행할코드 })
      .catch(()=>{ 요청실패시실행할코드 })

    }}>더보기</button>
  )
}

 

리액트에선 ajax를 사용할 때, 문법도 비슷한 axios와 fetch를 자주 쓴다.

 

axios와 fetch의 차이는 서버에서 데이터를 받아 올때, json형태(object와 비슷하지만 key 값이 문자열 처리 되어있음)로 받아와야 안전하게 전달할 수 있는데 axios 같은 경우는 json 데이터를 가져와서 object형태로 알아서 파싱해주지만 fetch의 경우는 json으로 받은 데이터를 object로 파싱하는 작업을 해야한다.

 

 

- post 요청

axios.post('URL', { id : 'test', pw : 1234})
  .then((result)=>{  })
  .catch(()=>{ })

get과 마찬가지로 요청 성공/실패의 경우 then, catch로 구분할 수 있으며 라이브러리에 header나 cookie 등의 정보도 보낼 수 있다.

 

 

 

'React' 카테고리의 다른 글

[React] chap.3  (0) 2021.12.14
[React] chap.1  (0) 2021.12.03

+ Recent posts