[리액트] 기초 개념 router-dom, props, state , memo, 상태값 불변 변수

AnSuebin·2022년 8월 17일
0

[리액트] 개념 정리

목록 보기
3/13
post-thumbnail

router-dom, props, state , memo, 상태값 불변 변수
1. SPA 페이지
2. react-router-dom
- BrowserRouter
- Link
- Router
3. useState
- useState
- props
- React.memo
- 불변변수로 관리하기 => 전개 연산자

4. 단일 페이지 어플리케이션(SPA)
1) MPA(멀티 페이지 애플리케이션) 와 SPA 비교

  • MPA : 페이지 전환 요청이 다시 서버로 요청을 보내고 서버는 또다시 HTML을 내려주는 방식.
  • SPA: 페이지 전환 요청이 있으면 서버로 항상 요청을 보내는 것이 아니고, 필요할 때만 데이터를 요청해서 받아오는 방식

2) SPA가 가능하기 위한 조건

  • 자바스크립트에서 브라우저로 페이지 전환 요청을 보낼 수 있어야 한다. 단 브라우저는 서버로 요청을 보내지 않아야한다.
  • 브라우저의 뒤로 가기와 같은 사용자의 페이지 요청을 자바스크립트에서 처리할 수 있어야한다. 마찬가지로 브라우저는 서버로 요청을 보내지 않아야 한다.

3) react-router-dom

import React from 'react';
import { BrowserRouter, Router, Link } from 'react-router-dom';
...

export default function App() {
    return (
        <BrowserRouter>
            <div>
                <Link to="/"></Link>
                <Link to="/photo">사진</Link>
                <Link to="/rooms">방 소개</Link>
                
                <Route exact path="/" component={Home} />
                <Route path="/photo" component={Photo} />
                <Route path="/rooms" component={Rooms} />
            </div>

    );
}
  • BrowserRouter: 현재 페이지의 상태값을 관리해준다.
  • Link: Link 컴포넌트를 사용하면 이 링크를 클릭했을 때 to에 해당하는 경로로 이동시켜준다
  • Route:
    Route 컴포넌트를 사용하면 path 값에 따라서 어떤 Component를 렌더링할지 결정을 해준다.
    Route 컴포넌트로 렌더링을 하면 해당 컴포넌트의 속성 값으로 match라는 속성 값을 넣어준다. 이 match 안에는 url이라는 속성이 있는데, 이 속성 값이 의미하는 것은 Rooms 컴포넌트가 렌더링될 당시에 매치됐던 그 url의 일부를 의미한다.
 export default function Rooms({ match }) {
    return (
        <div>
            ...
            <Link to={`${match.url}/blueRoom`}>파란 방으로 이동하기</Link>
            <Link to={`${match.url}/greenRoom`}>초록 방으로 이동하기</Link>
            ...
        </div>
    );
 }

5. 컴포넌트의 속성과 상태값
1-1) state 상태값이 없을 때의 문제

import React from 'react';

let color = 'red';

export default function App() {
  function onClick() {
    color = 'blue';
  }

  return (
    <button style={{ backgroundColor: color }} onClick={onClick}>
      좋아요
    </button>
  )
}
  • 외부에 변수를 만들어놓고 그 변수를 수정할 수 있는 구조다.
  • 하지만 클릭 이벤트가 발생해서 onClick 함수가 실행이 되어도 버튼 색이 파란색으로 변경되지 않는다.
  • 이것은 color 변수값을 변경은 했지만 리액트가 이 값이 변경됐다는 사실을 모르기 때문이다.
  • 리액트가 값의 변경 사실을 알려면 상태값으로 관리를 해야 한다.

1-2) state 상태값이 있다면

import React from 'react';

export default function App() {
  const [color, setColor] = useState('red');

  function onClick() {
    setColor('blue');
  }

  return (
    <button style={{ backgroundColor: color }} onClick={onClick}>
      좋아요
    </button>
  )
}
  • useState 함수를 호출하면 컴포넌트에 상태값을 추가할 수 있다.
  • useState 의 매개변수인 red는 상태값의 초기값을 의미한다.
  • useState 는 배열을 반환한다. 배열의 첫 번째 아이템은 상태값이고 두 번째 아이템은 상태값 변경 함수이다.
  • 상태값 변경함수인 setColor를 호출해서 상태값인 color가 변경되면 리액트는 자동으로 ui를 변경해준다.

2-1) props

  • 자식 컴포넌트
    props : 부모 컴포넌트로부터 전달 받은 속성값.
    객체의 비구조화 문법을 이용하면 사용할 때 props.{속성명} 을 입력하지 않고 바로 {속성명}으로 사용할 수 있기 때문에 좀 더 간편하게 작성할 수 있다.
import React from 'react';

export default function Title(props) {
  return <p>{props.title}</p>
}

// 위의 코드에서 객체의 비구조화 문법을 이용하면 아래와 같이 작성할 수 있다.
// export default function Title({ title }) {
// 	return <p>{title}</p>
// }
  • 부모 컴포넌트
    Counter 라는 컴포넌트에서 Title 컴포넌트를 자식 컴포넌트로 사용하고 있고 title이라는 속성값을 내려주고 있다.
    이 때 count라는 상태값을 기반으로 title값을 계산하고 있는데 count 값이 변경되면 Counter 컴포넌트는 다시 렌더링이 될거고 Title 컴포넌트도 다시 렌더링 된다. 이 때 새로 생성된 속성값을 받는다.
    부모 컴포넌트가 렌더링 될 때마다 자식 컴포넌트도 렌더링이 되는데, 이 때 자식의 속성값이 변경되지 않았을 때도 불필요하게 자식 컴포넌트가 렌더링 된다.
import React, { useState } from 'react';
import Title from './Title';

export default function Counter() {
  const [count, setCount] = useState(0);

  function onClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <Title title={`현재 카운트: ${count}`} />
      <button onClick={onClick}>증가</button>
    </div>
  );
}

3) React memo

  • 속성값이 변경될 때만 컴포넌트 렌더링 React.memo
import React from 'react';

function Title({ title }) {
    return <p>{title}</p>
}

export default React.memo(Title);

4) 불변 변수로 관리되는 속성값과 상태값

  • 불변 변수: 변수의 값을 바꿀 수 없는 것

  • 속성값

    • 속성값은 불변 변수이기 때문에 변경하려고 시도하면 에러가 발생함
    • 자식 컴포넌트에 전달되는 속성 값은 상위 컴포넌트에서 고나리하기 때문에 수정하지 못하도록 막혀있는 것.
  • 상태값

    • 상태값은 불변 변수가 아니지만 불변변수로 관리하는 것이 좋음
    • 불변 변수로 관리하면 코드의 복잡도도 낮아지는 장점이 있음
  • 불변변수로 관리하지 않은 코드

    • 버튼을 클릭해도 값이 증가되지 않는다.
    • 리액트는 상태값 변경 유무를 이전 값과의 단순 비교로 판단을 하는데 count가 지금 객체고 그런데 여기서 객체의 참조값은 변하지 않았다. 단순히 내부의 속성값만 변경된 상태다.
    • 그래서 리액트 입장에서는 이 값이 변경되지 않았다고 판단한다. 그래서 setCount를 호출한 것이 무시된다.
    • 따라서 상태값도 속성값과 마찬가지로 불변 변수로 관리하는 게 좋다.
    • 객체를 불변 변수로 관리하는 한 가지 방법은 전개 연산자를 이용하는 것이다.
import React, { useState } from 'react';
import Title from './Title';

export default function Counter() {
  const [count, setCount] = useState({ value: 0 });

  function onClick() {
    count.value += 1;
    setCount(count);
  }

  return (
    <div>
      <Title title={`현재 카운트: ${count.value}`} />
      <button onClick={onClick}>증가</button>
    </div>
  );
}

- 불변변수로 관리한 코드: 전개 연산자 문법에서 객체의 속성 값들을 풀어놓고 변경하고자 하는 값을 덮어 쓰는 방식이다.

import React, { useState } from 'react';
import Title from './Title';

export default function Counter() {
  const [count, setCount] = useState({ value: 0 });

  function onClick() {
    setCount({ ...count, value: count.value + 1 });
  }

  return (
    <div>
      <Title title={`현재 카운트: ${count.value}`} />
      <button onClick={onClick}>증가</button>
    </div>
  );
}

참고
https://jess2.xyz/react/react-tip-0/#2-create-react-app-cra-%EC%9C%BC%EB%A1%9C-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0

profile
고객에게 명료한 의미를 전달하고, 명료한 코드를 통해 생산성 향상에 기여하고자 노력합니다.

0개의 댓글