본문 바로가기

WINK-(Web & App)/React.js 스터디

[2025 1학기 React.js 스터디] 백채린 #3주차

반응형

시험기간 전 마지막 스터디 .. 아자아자화이팅 !!!!!!!!!!!!!!

 

 

 

1. 리액트는 어쩌다 만들어졌을까?

 

 

사용자와의 인터랙션이 자주 발생

➡️ 처리해야 할 이벤트, 관리해야 할 상태값, DOM이 다양해지게 되고 규칙도 많이 복잡해짐

➡️ Ember, Backbone, AngularJS 등의 프레임워크가 만들어짐

* 이 프레임워크들은 자바스크립트의 특정 값이 바뀌면 특정 DOM의 속성이 바뀌도록 연결해서 업데이트 

 

💡 상태가 바뀌었을 때, 아예 처음부터 새로 만들어서 보여주자는 아이디어에서 리액트가 시작

❓ 근데 이러면 속도가 매우 느리게 되지 않나?? 그래서 리액트에서는 Virtual DOM을 사용함

* 브라우저에 보여지는 DOM이 아닌 메모리에 가상으로 존재하는 DOM으로, JavaScript 객체이기 때문에 속도가 훨씬 빠름

즉, DOM의 상태를 메모리에 저장하고, 변경 전과 후의 상태를 비교한 뒤 최소한의 내용만 반영하는 것

 

출처: https://coding-medic.com/2020/11/10/the-virtual-dom/

 

Virtual DOM의 동작 원리

UI가 변경 감지 ➡️ UI를 Virtual DOM으로 렌더링(실제 화면이 아닌 가상 렌더링)

➡️ 이전과 현재 Virtual DOM을 비교해 차이 계산

➡️ 변경된 부분을 실제 DOM에 반영

 

❓ 만약 Virtual DOM이 없으면 ?

DOM은 변경된 빨간 부분뿐만 아니라 모든 동그라미들을 빨간색으로 바꿔서 렌더링함, 사소한 변경에도 전체가 리렌더링돼 비효율적

 

 

 

2. 작업환경 준비

 

 

❗️ 설치해야 할 것 ❗️

Node.js, Yarn, 코드 에디터(VSCode, WebStorm 등), Git Bash(윈도우의 경우에만 설치)

 

새 프로젝트 만들어보기(터미널에 작성)

// react-study 디렉터리 안에 리액트 프로젝트 생성
$ npm create-react-app react-study

 

$ cd react-study
$ npm start

 

 

이렇게 뜨면 성공이에요

 

 

 

 

3. 나의 첫번째 리액트 컴포넌트

 

 

src 내부에 Hello.js 파일을 만들고 아래 코드를 작성하고, App.js도 아래와 같이 수정해주세요

 

- 리액트 컴포넌트를 만들 땐

 

import React from 'react;

 

를 통해 리액트를 불러와줘야 함

 

- 컴포넌트를 내보내줘야 다른 컴포넌트에서 불러와서 사용할 수 있음

 

export default Hello;

 

 

결과 !!!

 

컴포넌트는 일종의 UI 조각이기 때문에 재사용 가능

 

 

id 가 'root'인 DOM을 선택하고 있는데 이 DOM은 public/index.html 안에 <div id="root"></div>에 있음

즉, 리액트 컴포넌트가 렌러딩될 때, 이 결과물이 위 div 내부에 렌더링되는 것

 

 

 

 

4. JSX

 

 

- JSX는 리액트에서 생김새를 정의할 때 사용하는 문법

 

* Babel https://bit.ly/2wMpkk2

 

Babel · Babel

The compiler for next generation JavaScript

babeljs.io

: 자바스크립의 문법을 확장해주는 도구,

  리액트 컴포넌트 파일에서 XML 형태로 코드를 작성하면 babel이 JSX를 JavaScript로 변환해줌

 

- JSX 규칙

 

1. 태그는 꼭 닫혀있어야 함 ex) <div></div>

* Self Closing 태그:  바로 닫히는 태그, 태그와 태그 사이에 내용이 들어가지 않을 때 사용

ex) <input />, <br />

 

2. 두개 이상의 태그는 무조건 하나의 태그로 감싸져있어야 함

* Fargment: 태그를 이름없이 작성하면 만들어짐, div 같은 걸로 감싸기 애매할 때 사용

 

3. JSX 안에 자바스크립트 값 사용하기

JSX 내부에 자바스크립트 변수를 보여줘야할 때에는  {}  으로 감싸서 보여줌

 

4. style과 className

인라인 스타일 ➡️ 객체 형태로 작성

 -  로 구분되어 있는 이름 ex) backgrount-color ➡️ camelCase 형태로 네이밍 ex) backgroundColor

 

css class를 설정 할 때에는 className= 으로 설정

 

 

5. 주석

JSX 내부 주석은 {/* 이런 형태로  */} 작성

열리는 태그 내부에서는 // 이런 형태로도 작성

 

 

 

 

5. props(properties)를 통해 컴포넌트에게 값 전달하기

 

 

App 컴포넌트  -- (name, color 이라는 값 전달) -->  Hello 컴포넌트 

- 컴포넌트에게 전달되는 props는 파라미터를 통해 조회, 객체 형태로 전달됨

 

 

- 코드를 간결하게 작성하기 위해서는 비구조화 할당 문법 사용 (Hello 컴포넌트에 props 대신에 {color, name} 전달)

- 컴포넌트에게 props를 지정하지 않았을 때  defaultProps  라는 값 설정

 

// Hello.js에 추가
Hello.defaultProps = {
    name: "이름 없음"
}

 

 

 

-  props.children 

: 컴포넌트 태그 사이에 넣은 값을 조회하고 싶을 때 사용

 

 

 

 

6. 조건부 렌더링

 

 

: 특정 조건에 따라 다른 결과를 렌더링하는 것 (삼항연산자 사용)

 

 

*  &&  연산자: 단순히 특정 조건이 true, false 일 경우 삼항연산자 대신 사용

 

// isSpecia이 true일 때 <b>**</b>
{isSpecial && <b>**</b>}

 

- props 값 설정을 생략하면, true로 설정한 것으로 간주

 

 

 

 

7. useState 를 통해 컴포넌트에서 바뀌는 값 관리하기

 

 

- 리액트 패키지에서 useState 라는 함수 불러오기

 

import React, {useState} from 'react';

 

- 첫 번째 함수는 현재 상태, 두 번째 원소는 Setter 함수

:  useState  함수를 통해 컴포넌트에서 상태를 관리할 수 있음

 

const [number, setNumber] = useState(0);

 

- useState를 통해 Counter 컴포넌트 만들어보기

* on이벤트이름 = {실행하고싶은함수} ex) onClick = {onIncrease} → 이때, 함수형태를 넣어줘야 함 onClick = {onIncrease()} ❌

 

 

 

 

 

 

8. input 상태 관리하기

 

 

-  onChange  이벤트

이벤트 객체 e를 차라미터로 받아와서 e.target을 통해 이벤트가 발생한 DOM을 가르킴

이 DOM의 value 값 (e.target.value) 를 조회하면 input에 입력한 값을 알 수 있음

 

 

 

 

 

 

9. 여러개의 input 상태 관리하기

 

 

* placeholder: input이 비어져있을 때 이 input에 대한 설명을 보여줌

- spread 문법 (... 문법)

: 객체의 내용을 모두 "펼쳐서" 기존 객체를 복사해줌 (불변성을 지킨다)

* 불변성일 지켜주어야만 리액트 컴포넌트에서 상태가 업데이트 됐음을 감지할 수 있고 이에 따라 필요한 리렌더링이 진행됨

 

setInputs({
  ...inputs,
  [name]: value
});

 

- 리액트에서 객체를 업데이트하게 될 때에는 기존 객체를 직접 수정하지 않고 새로운 객체를 만들어서, 새 객체에 변화를 주어야 함

inputs[name] = value 과 같이 기존 객체를 직접 수정하면, 값은 바꿔도 리렌더링 ❌

 

 

 

 

 

 

📝 과제 📝

 

  • 과제: 자기소개 카드 만들기
    • 조건 1. 이름, 나이, 취미를 Props로 전달받아 출력
    • 조건 2. 버튼 클릭 시 좋아하는 음식을 변경하도록 State를 사용해 구현

 

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

const Wrapper = styled.div`
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100vh;
        background-color: #fef3f7;
    `;

const Box = styled.div`
        background-color: #ffffff;
        width: 300px;
        padding: 20px;
        border-radius: 16px;
        box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
        font-family: 'Helvetica', sans-serif;
        font-size: 16px;
        color: #333;
    `;

const Label = styled.div`
        margin-bottom: 8px;
        line-height: 1.6;
    `;

const Input = styled.input`
        width: 80%;
        padding: 8px;
        margin-top: 4px;
        margin-bottom: 12px;
        border: 1px solid #ccc;
        border-radius: 8px;
        font-size: 14px;
        outline: none;
        transition: border 0.2s;

        &:focus {
            border-color: #ee7ea0;
        }
    `;

const Button = styled.button`
        padding: 8px 16px;
        background-color: #ee7ea0;
        color: white;
        border: none;
        border-radius: 8px;
        font-size: 14px;
        cursor: pointer;
        transition: background-color 0.3s;

        &:hover {
            background-color: #e4608c;
        }
    `;

function Card({ name, age, hobby }) {
    const [value, setValue] = useState('');

    const onChange = (e) => {
        setValue(e.target.value);
    }

    const onClick = () => {
        setValue('');
    }

    return (
        <Wrapper>
            <Box>
                <Label>이름: {name}</Label>
                <Label>나이: {age}</Label>
                <Label>취미: {hobby}</Label>
                <Label>좋아하는 음식: {value}</Label>
                <Input onChange={onChange} value={value} placeholder="좋아하는 음식이 먼가요" />
                <Button onClick={onClick}>변경</Button>
            </Box>
        </Wrapper>
    )
}

export default Card;

 

 

결과입니다 흐흐 저 변경 버튼 홍보부색이에요 🩷

 

변경 버튼을 누르면 초기화가 됩니다.!!!!!

 

 

반응형