리액트 기초반 3주차(1)

2022. 2. 1. 17:01코딩공부/React

Event Listner

이벤트 리스너는 사용자가 어떤 행동(=이벤트)을 하는 지 아닌 지 지켜보다가 알려주는 것입니다. 대표적으로는 마우스 클릭, 터치, 마우스 오버, 키보드 누름 등이 자주 쓰여요!

 

클래스형 컴포넌트

이벤트 리스너는 어디에 위치해야할까요? 클릭을 하건, 마우스를 올리건 DOM 요소가 있어야 이벤트가 발생하는 지 지켜볼 수 있겠죠?

→ 네! componentDidMount()에 넣어주면 됩니다.

 

이벤트는 꼭 컴포넌트가 사라지면 지워주세요!

이 과정을 clean up 이라고 불러요.

개발자 도구에서 확인했듯, 이벤트는 한번 등록되면 계속 남아있거든요!

그런데 컴포넌트가 사라지면요? 이벤트가 실행되지는 않겠지만, 남아는 있을거예요. 😢

그러니 깨끗하게 정돈해주는 과정이 필요합니다! 그게 clean up이고요!

 

함수형 컴포넌트

이벤트 리스너는 어디에 위치해야할까요? 클릭을 하건, 마우스를 올리건 DOM 요소가 있어야 이벤트가 발생하는 지 지켜볼 수 있겠죠?

→ 그럼 함수형 컴포넌트에서는 componentDidMount() 역할을 하는 친구를 가져다 써야겠네요! useEffect()을 써봅시다!

 

useEffect에서 clean up은 return 구문을 이용해서 합니다!

  // 첫번째 인자는 익숙하죠! 화살표 함수! 넵, 렌더링 시 실행할 함수가 여기에 들어갑니다.
  // 두번째 인자의 []! 디펜던시 어레이라고 불러요. 여기 넣어준 값이 변하면 첫번째 인자인 
  // 콜백함수를 실행합니다.
  // // 두번째 인자가 없으면 화살표함수가 한번만 실행되고 다시는 실행되지 않는다.
  React.useEffect(() => {
    // 여기가 rendering 때 실행될 구문이 들어가는 부분입니다.
    // componentDidMount, componentDidUpdate일 때 동작하는 부분이 여기예요.
    text.current.addEventListener("mouseover", hoverEvent);
    
    return () => {
        // 여기가 clean up 부분입니다.
        // componentWillUnmount 때 동작하는 부분이 여기예요.
        text.current.removeEventListener("mouseover", hoverEvent);
    };
  }, [text]);

 

 

라우팅

SPA

Single Page Application!

말 그대로 서버에서 주는 html이 1개 뿐인 어플리케이션이에요. 전통적인 웹사이트는 페이지를 이동할 때마다 서버에서 html, css, js(=정적자원들)을 내려준다면, SPA는 딱 한번만 정적자원을 받아옵니다.

 

장점 :

- 사용성이 좋다. 페이지를 이동할 때마다 서버에서 주는 html로 화면을 바꾸다보면 상태 유지가 어렵고, 바뀌지 않은 부분까지 새로 불러오니까 비효율적이거든요. (사용자가 회원가입하다가 적었던 내용이 날아갈 수도 있고, 블로그같은 경우, 페이지마다 새로 html을 받아오면 바뀐 건 글 뿐인데 헤더와 카테고리까지 전부 다시 불러와야 합니다.)

 

단점 :

SPA는 딱 한 번 정적자원을 내려받다보니, 처음에 모든 컴포넌트를 받아옵니다.

즉, 사용자가 안들어가 볼 페이지까지 전부 가지고 옵니다. 게다가 한 번에 전부 가지고 오니까 아주아주 많은 컴포넌트가 있다면 첫 로딩 속도가 느려집니다.

 

라우팅이란?

SPA는 주소를 어떻게 옮길 수 있을까? html은 딱 하나를 가지고 있지만, SPA도 브라우저 주소창대로 다른 페이지를 보여줄 수 있어요. 이렇게 브라우저 주소에 따라 다른 페이지를 보여주는 걸 라우팅이라고 부릅니다.

 

react-router-dom 패키지 설치

yarn add react-router-dom@5.2.1

react-router-dom 공식문서 : 

https://v5.reactrouter.com/web/guides/primary-components

 

Declarative routing for React apps at any scale | React Router

Version 6 of React Router is here! React Router v6 takes the best features from v3, v5, and its sister project, Reach Router, in our smallest and most powerful package yet.

reactrouter.com

 

BrowserRouter: 페이지가 실제로 주소창을 참고해서 이동하도록함. 주소창 보고 내 컴포넌트를 분기할 수 있게함.

Route : path에 맞게 안에 요소를 보여줄거다!

 

라우팅 처리를 통한 페이지 전환

1. index.js에 BrowserRouter 적용하기

BrowserRouter(브라우저라우터)는 웹 브라우저가 가지고 있는 주소 관련 정보를 props로 넘겨주는 친구입니다.

현재 내가 어느 주소를 보고 있는 지 쉽게 알 수 있게 도와줘요.

// BrowserRouter 적용하기
import React from 'react';
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

// 이부분이 index.html에 있는 div#root에 우리가 만든 컴포넌트를 실제로 랜더링하도록 
// 연결해주는 부분입니다.
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 

2. 세부 화면 만들기

 

3. App.js에서 Route 적용하기

4. exact 적용하기

import { Route } from "react-router-dom";
import Home from "./Home"
import Cat from "./Cat"
import Dog from "./Dog"

function App() {
  return (
    <div className="App">
      <Route path="/" exact>
        {/* exact 속성이 없으면 포함하면 다보여줌
        들어가게 되면 패스가 완전히 똑같으면 보여줌! */}
        <Home data = {"im data"}/>
        {/* 페이지에 데이터 주는 법 */}
      </Route>
      <Route path="/cat">
        <Cat/>
      </Route>
      <Route path="/dog">
        <Dog/>
      </Route>
    </div>
  );
}

export default App;

 

5. URL 파라미터사용하기(동적라우팅)

→ 파라미터: /cat/nabi

→ 쿼리: /cat?name=nabi (?key값=value값)

 

속성을 사용하여 파라미터 주는 방법

//App.js
...
// 파라미터 주기
<Route path="/cat/:cat_name" component={Cat}/>

...
//Cat.js
import React from "react";

const Cat = (props) => {

    console.log(props.match);

    return (
        <div>고양이 화면이에요.</div>
    )
}

export default Cat;

useParams 훅을 사용하여 파라미터 주는 방법

import React from "react";
import { useParams } from "react-router-dom";
const Cat = (props) => {
    const cat_name = useParams();
    console.log(cat_name);
    // console.log(props);
  return (
      <div>고양이 화면입니다!</div>
  );
};

export default Cat;

 

6. 링크 이동 시키기

- <Link/> 사용하기

링크 컴포넌트는 html 중 a 태그와 비슷한 역할을 해요. 리액트 내에서 페이지 전환을 도와줍니다.

<Link to="주소">[텍스트]</Link>

- history 사용하기

props로 history 객체를 받아 이동하기

import React from "react";

const Dog = (props) => {
  // props의 history 객체를 살펴봅시다.
  console.log(props);

  // 그리고 history.push('/home')으로 페이지 이동도 해봐요!

  return (
    <div
      onClick={() => {
        props.history.push("/home");
      }}
    >
      강아지 화면이에요.
    </div>
  );
};

export default Dog;

꼭 props에서 받아오지 않아도, useHistory 훅을 사용하면 간단히 history 객체에 접근할 수 있어요! 페이지 이동할 때 써먹으면 엄청 편하겠죠.

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

const Home = (props) => {
  let history = useHistory();
  return (
    <>
      <div>메인 화면이에요.</div>

      <button
        onClick={() => {
          history.push("/cat");
        }}
      >
        cat으로 가기
      </button>
    </>
  );
};

export default Home;

 

잘못된 주소 처리하기

스위치 사용

import React from "react";
import styled from "styled-components";
import {Route, Switch} from "react-router-dom";

// BucketList 컴포넌트를 import 해옵니다. import [컴포넌트 명] from [컴포넌트가 있는 파일경로];
import BucketList from "./BucketList";
import Detail from "./Detail";
import NotFound from "./NotFound";

function App() {

    const [list, setList] = React.useState(["영화관 가기", "매일 책읽기", "수영 배우기"]);
    const text = React.useRef(null);

    const addBucketList = () => {
        // 스프레드 문법! 기억하고 계신가요? :) 원본 배열 list에 새로운 요소를 추가해주었습니다.
        setList([
            ...list,
            text.current.value
        ]);
    }

    console.log(list);
    return (
        <div className="App">
            <Container>
                <Title>내 버킷리스트</Title>
                <Line/> {/* 컴포넌트를 넣어줍니다. */}
                {/* <컴포넌트 명 [props 명]={넘겨줄 것(리스트, 문자열, 숫자, ...)}/> */}
                <Switch>
                    <Route path="/" exact render={(props) => (<BucketList list={list}/>)}/>
                    <Route path="/detail" component={Detail}/>
                    <Route component={NotFound}/>
                </Switch>
                {/* 스위치 안에 있는 경로들을 하나씩 하나씩 비교하고 전부 안맞으면 
                패스 지정 안한 마지막 경로가 뜸 */}

            </Container>
            {/* 인풋박스와 추가하기 버튼을 넣어줬어요. */}
            <Input>
                <input type="text" ref={text}/>
                <button onClick={addBucketList}>추가하기</button>
            </Input>
        </div>
    );
}

'코딩공부 > React' 카테고리의 다른 글

리액트 기초반 4주차  (0) 2022.02.03
리액트 기초반 3주차(2)  (0) 2022.02.02
리액트 기초반 2주차(2)  (0) 2022.01.31
리액트 기초반 2주차(1)  (0) 2022.01.29
리액트 기초반 1주차(3)  (0) 2022.01.28