본문 바로가기

FE

React + hook + Styled-Component

React 란 무엇인가

 

React는 웹 프레임워크로, 자바스크립트 라이브러리의 하나로서 사용자 인터페이스를 만들기 위해 사용된다.

 

"컴포넌트" 라고 불리는 작고 고립된 코드의 파편을 이 용하여 복잡한 UI를 구성하도록 도움

 

 

React 의 장/단점

장점

1. index.html 파일을 다운받으면 필요한 부분만 업데이트 한다. -> 빠른 상호작용

2. 전체 페이지를 렌더링 할 필요가 없다

단점

1. 웹 애플리케이션에 필요한 모든 정적 리소스를 최초 한번에 다운로드 -> 초기 로딩이 느리다

2. 검색 엔진 최적화에 불리하다. -> 검색 엔진은 파일단위로 보기 때문..

 

DOM

  • HTML 문서를 트리 구조(DOM Tree)로 표현한 것. 각 태그 → 노드(node).
  • JS/CSS가 이 트리를 읽고 수정하면서 화면이 바뀜.
  • Recalculate Style: 스타일 다시 계산
  • Reflow: 크기·위치 변경 시
  • Repaint: 픽셀 다시 칠하기(색상만 바뀌면 보통 Repaint만)
  • 색상 변경은 보통 Repaint만 일어나고, 크기/배치 변경은 Reflow+Repaint가 발생해 더 비쌈

Virtual DOM 이란?

  • 실제 DOM의 가벼운 JS 객체 복사본을 메모리에 유지.
  • 리액트는 렌더링마다
    1. 이전 VDOM새 VDOM을 만들고 비교(diff)
    2. 달라진 부분만 패치(실제 DOM에 최소 변경)
      → 불필요한 Reflow/Repaint를 줄여 효율적인 업데이트.

 

React 특징

Props 부모 컴포넌트에서 자식 컴포넌트로 전달해주는 데이터

State 특정 컴포넌트가 갖는 상태 (값)

 

JSX 문법 : 하나의 파일에 Javascript와 HTML을 동시에 작성하여 편리함 가독성이 높고 작성하기 쉬움

 if -> 삼항 연산자 사용 (return 안에서)

→ JSX 안에서 자바스크립트 표현식을 작성하려면 {}로 감싸준다

 반드시 부모 요소가 감싸는 형태

→ class => className, onclick -> onClick

 

 

React Hooks

1-1 ) useState : 상태 관리 훅

  • 함수형 컴포넌트에서는 state 관리를 할 수 없었음!
  • useState라는 훅을 사용하여 함수형 컴포넌트에서도 상태 관리가 가능해졌다.
const [state, setState] = useState(initialState);
  • 반환:
    • state : 현재 값
    • setState(next) : 값 갱신 함수
  • 초기값은 숫자/문자/배열/객체 등 자유.

1-2) useState로 Counter 만들기

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <h1>Counter Component</h1>
      <p>클릭을 {count}번 했어요!</p>
      {/* count는 현재 상태 값인 count를 동적으로 표시 */}
      <button onClick={() => setCount(count + 1)}>증가 버튼!</button>
      {/* 버튼이 클릭될 때 setCount 함수를 호출하여 count 값을 1 증가 */}
    </div>
  );
}

export default Counter;
import "./App.css";
import Counter from "./components/Counter";

function App() {
  return (
    <>
      <Counter />
    </>
  );
}

export default App;
 

1-3) useState 실습 

아래 버튼을 클릭하면 두 상태가 반복해서 변하도록 설정

// UseStatePrac.jsx
import React, { useState } from "react";

function UseStatePrac() {
  const [likelion, setLikelion] = useState(true);

  return (
    <div>
      {likelion ? <h1>멋사 안녕</h1> : <h1>누구세요</h1>}
      <button onClick={() => setLikelion(!likelion)}>
        {/* 삼항 연산자 이용해서, 조건에 따라 상태값 변경 */}
        상태 변경
      </button>
    </div>
  );
}

export default UseStatePrac;

 

2) 라이프 사이클

React에서 컴포넌트는 생성되고, 업데이터 되고 , 사라지는 과정을 거친다.

이를 라이프 사이클 (생명주기) 라고 한다.

 

  • Mount: 처음 나타날 때 실행되고, 아래 작업이 다 끝나면 화면이 그려진다
    • 1. constructor() - 컴포넌트를 초기화 하는 함수 (state, props 설정)
    • 2. render() - JSX 를 리턴해서 화면에 그릴 준비
    • 3. componentDidMount() - class형 컴포넌트에서는 이걸 사용했지만 함수형 컴포넌트에서는 후술할 useEffect로 대체
  • Update: state/props 변경으로 다시 렌더링될 때마다 실행
  • Unmount: 화면에서 사라질 때 실행

3-1) useEffect

  • 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 Hook
  • 컴포넌트가 mount 됐을 때, unmount 됐을 때, update 됐을 때 특정 작업을 처리한다!
useEffect(() => {
  // 실행할 코드
}, [의존성]);

useEffect(function, dependencies)

// function : 랜더링 이후 실행할 함수(Mount, update)
// deps: 배열 값이 변하면 함수 실행
//     - 생략: Mount & Update시 동작
//     - [] : 빈배열 -> Mount 시에만 동작
//     - [data] : 배열 안의 data 값이 Update 시 동작

 

ex)  사용하는 경우 : 데이터를 가져오거나 업데이트 할 때, state/props가 바뀌었을 때 등..

 

3-2) useEffect 로 Counter 만들기

// UseEffectCounter.jsx
import { useState, useEffect } from "react";

const UseEffectCounter = () => {
  // count State 생성
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log(`렌더링 완료! count의 값은 ${count}입니다.`);
  }); // 여기서는 deps가 없이 함수만 있기 때문에 mount, update 시마다 실행됨!

  return (
    <>
      <h1>Counter Component with useEffect</h1>
      <p>클릭을 {count}번 했어요!</p>
      <button onClick={() => setCount(count + 1)}>증가 버튼!</button>
    </>
  );
};

export default UseEffectCounter;

 

styled-components

  • CSS-in-JS: JS 파일 안에서 백틱 템플릿으로 CSS 작성.
  • 장점
    • 클래스/선택자 충돌 방지(로컬 스코프)
    • 컴포넌트 파일로 응집 → “이 스타일이 어디서 왔지?” 문제 해소
    • props로 동적 스타일 간편
  • 문법
      1. 이름의 첫 글자는 대문자로!
      2. HTML 태그를 styled.[태그]와 같은 형태로 선언합니다.
      3. 백틱(`) 으로 감싸기

ex) props를 활용해서 하나의 컴포넌트를 다양하게 이용 가능

//Box.jsx
import React from "react";
import styled from "styled-components";

const BoxWrapper = styled.section`
  background-color: ${(props) => props.color};
  width: 200px;
  height: 200px;
  text-align: center;
  line-height: 200px;
`;

export function Box({ label, color }) {
  return <BoxWrapper color={color}>{label}</BoxWrapper>;
}
//App.jsx
import "./App.css";
import { Box } from "./components/Box";

function App() {
  return (
    <>
      <Box label="빨강박스" color="red" />
      <Box label="파랑" color="blue" />
    </>
  );
}

export default App;

 

styled component 실습 - 버튼 컴포넌트 만들기

 

 

1번 버튼 : 클릭시 콘솔창에 ‘리액트 어렵죠..?’ 라고 찍히도록!

2번 버튼 : 클릭 시 콘솔창에 “세션 끝내기!’ 라고 찍히도록!

 

 

 

// Button.jsx
import React from "react";
import styled from "styled-components";

const BoxWrapper = styled.div`
  background-color: ${(props) => props.color};
  width: 200px;
  height: 200px;
  text-align: center;
  line-height: 200px;
`;

export function Button({ label, bgColor,buttonHandler }) {
  return <BoxWrapper color={color} onClick={buttonHandler}>{label}</BoxWrapper>;
}
// App.jsx
import "./App.css";
import {Button} from "./components/Button";

function App() {
  const onClickButton1 = () => {
    console.log("리액트 어렵죠..? ㅠㅠ");
  };

  const onClickButton2 = () => {
    console.log("세션끝났다!");
  };

  return (
    <>
      <Button
        label={"리액트 어렵죠..? ㅠㅠ"}
        bgColor={"#5e3afd"}
        buttonHandler={onClickButton1}
      />

      <Button
        label={"세션 끝내기!"}
        bgColor={"#2c9c4e"}
        buttonHandler={onClickButton2}
      />
      <Button />
    </>
  );
}

export default App;