Front/React

리액트 ES6 문법 정리 - 기본편

oodada 2024. 3. 29. 12:52
반응형

리액트 ES6 문법 정리

리액트는 ES6 문법을 사용하여 개발합니다. ES6는 자바스크립트의 표준 버전으로, 보다 간결하고 효율적인 코드 작성을 가능하게 합니다. 이번 장에서는 ES6 문법을 정리하고, 리액트에서 사용하는 주요 문법을 알아보겠습니다.

1. 변수

변수는 let, const 키워드를 사용하여 선언한다.

변수란 데이터를 담는 공간을 의미합니다. 변수를 선언할 때는 var, let, const 키워드를 사용합니다.

  • let : 재할당할 수 있는 변수를 선언할 때 사용한다. 값을 변경할 수 있다.
  • const : 상수를 선언할 때 사용한다. 값을 변경할 수 없는 값을 명확하게 표시할 때 사용한다. 의도치 않은 값 변경을 방지한다.
  • var : 변수를 선언할 때 사용한다. ES6 이전에 사용하던 키워드로 가급적 사용을 지양한다.
// 변경 가능한
let a = 1
a = 2
console.log(a) // 2

// 변경 불가능한
const b = 1
b = 2 // TypeError: Assignment to constant variable.

리액트 애플리케이션에서 콘솔에 로그가 두 번 출력되는 현상

리액트 애플리케이션에서 콘솔에 로그가 두 번 출력되는 현상은 `React.StrictMode` 컴포넌트 때문에 발생합니다. `React.StrictMode`는 개발 모드에서만 활성화되며, 애플리케이션 내부의 잠재적 문제를 식별하기 위해 부수 효과를 포함한 일부 생명주기 메서드를 두 번씩 호출합니다. 이는 앱의 로그인, 상태 업데이트, 재렌더링 등을 검사하여 안전하지 않은 생명주기 사용, 레거시 API의 사용, 예측할 수 없는 부수 효과 등을 찾아내기 위함입니다.

코드에서 ReactDOM.createRoot(...).render(...)에 전달된 <React.StrictMode>가 이러한 행동의 원인입니다. 이 모드는 실제 프로덕션 빌드에서는 아무런 영향을 주지 않으며, 개발 중에만 추가 검사와 경고를 제공합니다. 따라서 콘솔 로그가 두 번 호출되는 것은 이중 렌더링을 통해 문제를 조기에 발견하고자 하는 의도적인 동작입니다.

2. 데이터 타입

리액트에서 데이터를 다루기 위해서는 자바스크립트의 기본 데이터 타입에 대한 이해가 필수적입니다. 이번 장에서는 자바스크립트의 주요 데이터 타입들을 살펴보고, 각 타입이 리액트 개발에서 어떻게 활용되는지 알아보겠습니다.

- 문자열(String)

문자열은 텍스트 데이터를 표현하는 데 사용됩니다. 리액트에서는 컴포넌트의 속성값이나 내용을 표현할 때 자주 사용됩니다. 문자열은 작은 따옴표('')나 큰 따옴표("")로 감싸서 표현합니다.

function Data() {
    const name = '리액트!'
    return <h1>안녕 난 {name}야!</h1>
}

- 숫자(Number)

숫자 타입은 정수나 소수 등의 숫자 데이터를 다룰 때 사용됩니다. 컴포넌트의 크기, 간격, 배열의 인덱스 등 다양한 곳에서 활용됩니다.

function Data() {
    const age = 10
    return <p>{age}년 전에 출시됐어.</p>
}

- 불리언(Boolean)

불리언은 참(true)과 거짓(false)의 두 가지 값만을 가지며, 조건문이나 토글 상태 등을 다룰 때 사용됩니다.

function Data() {
    const visible = true
    return {visible ? <p>보인다!</p> : <p>안보인다!</p>}
}

- 객체(Object)

객체는 키와 값의 쌍으로 이루어진 데이터 구조로, 여러 데이터를 하나의 단위로 그룹화하여 관리할 수 있습니다. 컴포넌트의 상태(state)나 속성(props)을 다룰 때 주로 사용됩니다.

function Data() {
    const user = {
        name: '리액트',
        age: 10,
    }

    return (
        <p>
            {user.name}의 나이는 {user.age}살이야.
        </p>
    )
}

- 배열(Array)

배열은 여러 개의 데이터를 순서대로 나열한 구조입니다. 리스트나 메뉴 항목 등, 순서가 있는 데이터를 표현할 때 유용합니다.
제로 기반 인덱스를 사용하며, 배열의 첫 번째 요소는 0부터 시작합니다.

function Data() {
    const array = [1, 2, 3]

    return (
        <ul>
            <li>{array[0]}</li>
            <li>{array[1]}</li>
            <li>{array[2]}</li>
        </ul>

        // map 함수를 사용하여 반복문을 대신할 수 있다.
        <ul>
            {array.map((item) => (
                <li>{item}</li>
            ))}
        </ul>
    )
}

- 배열 & 객체

배열과 객체는 서로 중첩하여 사용할 수 있습니다.

function Data() {
    const users = [
        {
            id: 1,
            name: '봄',
            age: 2,
        },
        {
            id: 2,
            name: '여름',
            age: 3,
        },
        {
            id: 3,
            name: '가을',
            age: 1,
        },
        {
            id: 4,
            name: '겨울',
            age: 5,
        },
    ]

    return (
        <ul>
            <li>
                {users[0].name}이는 {users[0].age}살
            </li>
            <li>
                {users[1].name}이는 {users[1].age}살
            </li>
            <li>
                {users[2].name}이는 {users[2].age}살
            </li>
        </ul>

        // map 함수를 사용하여 반복문을 대신할 수 있다.
        <ul>
            {users.map((user) => (
                <li key={user.id}>
                    {user.name}이는 {user.age}살
                </li>
            ))}
        </ul>
    )
}

- 함수(Function)

함수는 일련의 처리를 한 덩어리로 묶어 놓은 코드의 집합입니다. 재사용성이 높고, 유지보수가 쉽다는 장점이 있습니다. 리액트에서는 컴포넌트의 생명주기 함수나 이벤트 처리 함수 등을 함수로 정의하여 사용합니다.

// 함수 선언식 (기명 함수)
function Func1() {
    return (
        <div>
            <h1>안녕 난 리액트야!</h1>
            <p>리액트는 재밌어.</p>
        </div>
    )
}

// 함수 표현식 (익명 함수)
const Func2 = function () {
    return (
        <div>
            <h1>안녕 난 리액트야!</h1>
            <p>리액트는 재밌어.</p>
        </div>
    )
}

// 화살표 함수
const Func3 = () => {
    return (
        <div>
            <h1>안녕 난 리액트야!</h1>
            <p>리액트는 재밌어.</p>
        </div>
    )
}

function Data() {
    return (
        <div>
            <Func1 />
            <Func2 />
            <Func3 />
        </div>
    )
}

- undefined & null

undefined는 선언된 변수에 값이 할당되지 않았을 때의 기본값입니다. 반면, null은 개발자가 명시적으로 "값이 없음"을 나타내고자 할 때 사용합니다. 이 두 타입은 데이터가 '없음'을 나타내지만, 사용 의도에 따라 구분해서 사용합니다.

  • null : 값이 없음을 의미한다.
  • undefined : 값이 할당되지 않은 상태를 의미한다.
function Data() {
    const info = {
        birth: '2021-01-01',
        phone: null,
    }

    console.log(info.birth) // 2021-01-01
    console.log(info.phone) // null
    console.log(info.address) // undefined

    return (
        {/* 값이 있으면 출력, 없으면 '주소 정보 없음' 출력 */}
        <ul>
            <li>{info.birth || '주소 정보 없음'}</li>
            <li>{info.phone || '주소 정보 없음'}</li>
            <li>{info.address || '주소 정보 없음'}</li>
        </ul>
    )
}

- 실습 문제 1. 데이터 타입과 조건문 활용하기

자바스크립트의 기본 데이터 타입과 조건문을 사용하여 사용자의 로그인 상태를 표시하는 리액트 컴포넌트를 만드세요.

1. `isLogged`이라는 이름의 `const` 변수를 선언하고, 불리언(`true` 또는 `false`) 값을 할당하세요.
2. `isLogged` 값에 따라 "로그인됨" 또는 "로그인되지 않음"을 표시하는 간단한 리액트 컴포넌트를 작성하세요.
3. `isLogged`이 `true`일 경우 `<p>로그인</p>`을, `false`일 경우 `<p>로그아웃</p>`을 반환하도록 조건문을 사용하세요.

3. 연산자

리액트에서 연산자는 데이터를 처리하거나, 조건부 렌더링을 구현할 때 매우 유용하게 사용됩니다. 여기에는 산술 연산자뿐만 아니라, 비교 연산자, 논리 연산자, 삼항 연산자 등이 포함됩니다. 이제 리액트 컴포넌트에서 연산자를 활용하는 몇 가지 예시를 살펴보겠습니다.

- 산술 연산자

산술 연산자는 숫자 데이터를 다룰 때 주로 사용됩니다. 예를 들어, 숫자를 증가시키거나, 감소시키는 카운터 컴포넌트를 구현할 때 활용할 수 있습니다.

  • + : 덧셈 연산자
  • - : 뺄셈 연산자
  • * : 곱셈 연산자
  • / : 나눗셈 연산자
  • % : 나머지 연산자
function Operator() {
    let a = 1
    let b = 2

    return (
        <div>
            <h2>산술 연산자</h2>
            <p>
                {a} + {b} = {a + b} {/* 1 + 2 = 3 */}
            </p>
            <p>
                {a} - {b} = {a - b} {/* 1 - 2 = -1 */}
            </p>
            <p>
                {a} * {b} = {a * b} {/* 1 * 2 = 2 */}
            </p>
            <p>
                {a} / {b} = {a / b} {/* 1 / 2 = 0.5 */}
            </p>
            <p>
                {a} % {b} = {a % b} {/* 1 % 2 = 1 */}
            </p>
        </div>
    )
}

export default Operator

- 증감 연산자

증감 연산자는 변수의 값을 1씩 증가시키거나 감소시킬 때 사용됩니다. 전위 연산자와 후위 연산자로 나뉘며, 변수의 값을 증가시킨 후에 반환할지, 반환한 후에 증가시킬지를 결정합니다.

  • ++ : 변수의 값을 1 증가시킨다.
  • -- : 변수의 값을 1 감소시킨다.
function Operator() {
    let c = 1
    let d = 1

    return (
        <div>
            <h2>증감 연산자</h2>
            <p>
                c = {c} {/* 1 */}
            </p>
            <p>
                ++c = {++c} {/* 2 선연산 후출력 */}
            </p>
            <p>
                c = {c} {/* 2 */}
            </p>
            <p>
                d = {d} {/* 1 */}
            </p>
            <p>
                d++ = {d++} {/* 1 선출력 후연산 */}
            </p>
            <p>
                d = {d} {/* 2 */}
            </p>
        </div>
    )
}

export default Operator

- 비교 연산자

비교 연산자는 두 값을 비교하여 참(true) 또는 거짓(false)을 반환합니다. 주로 조건문에서 사용되며, 두 값이 같은지, 다른지, 큰지, 작은지 등을 비교할 때 활용됩니다.

  • === : 값과 자료형이 같은지 비교한다.
  • !== : 값과 자료형이 다른지 비교한다.
  • > : 왼쪽 값이 오른쪽 값보다 큰지 비교한다.
  • < : 왼쪽 값이 오른쪽 값보다 작은지 비교한다.
  • >= : 왼쪽 값이 오른쪽 값보다 크거나 같은지 비교한다.
  • <= : 왼쪽 값이 오른쪽 값보다 작거나 같은지 비교한다.
function Operator() {
    let e = 1
    let f = 2

    return (
        <div>
            <h2>비교 연산자</h2>
            <p>
                {`${e} === ${f} : ${e === f}`} {/* 1 === 2 : false */}
            </p>
            <p>
                {`${e} !== ${f} : ${e !== f}`} {/* 1 !== 2 : true */}
            </p>
            <p>
                {`${e} > ${f} : ${e > f}`} {/* 1 > 2 : false */}
            </p>
            <p>
                {`${e} < ${f} : ${e < f}`} {/* 1 < 2 : true */}
            </p>
            <p>
                {`${e} >= ${f} : ${e >= f}`} {/* 1 >= 2 : false */}
            </p>
            <p>
                {`${e} <= ${f} : ${e <= f}`} {/* 1 <= 2 : true */}
            </p>
        </div>
    )
}

export default Operator

- 논리 연산자

논리 연산자는 논리적인 연산을 수행할 때 사용됩니다. 주로 조건문에서 사용되며, 두 값이 모두 참일 때 참을 반환하는 AND 연산자(&&), 두 값 중 하나라도 참일 때 참을 반환하는 OR 연산자(||), 값을 부정하는 NOT 연산자(!) 등이 있습니다.

  • && : 논리 AND 연산자
  • || : 논리 OR 연산자
  • ! : 논리 NOT 연산자
function Operator() {
    return (
        <div>
            <h2>논리 연산자</h2>
            <p>{`true && true = ${true && true}`}</p> {/* 두 조건이 모두 참일 경우 true 반환 */}
            <p>{`true && false = ${true && false}`}</p>{' '}
            {/* 두 조건 중 하나가 거짓이므로 첫 번째 거짓인 값인 false 반환 */}
            <p>{`true || false = ${true || false}`}</p> {/* 두 조건 중 하나라도 참일 경우 true 반환 */}
            <p>{`false || false = ${false || false}`}</p> {/* 두 조건이 모두 거짓일 경우 false 반환 */}
            <p>{`!true = ${!true}`}</p> {/* 부정연산자 : 조건이 참일 경우 false 반환 */}
            <p>{`!false = ${!false}`}</p> {/* 부정연산자 : 조건이 거짓일 경우 true 반환 */}
        </div>
    )
}

export default Operator

- 조건 연산자

조건 연산자는 조건문을 간단하게 표현할 때 사용됩니다. 조건식이 참일 때와 거짓일 때의 값을 각각 반환합니다.

  • 조건 ? 참 : 거짓
function Operator() {
    return (
        <div>
            <h2>조건 연산자</h2>
            <p>{`true ? '참' : '거짓' = ${true ? '참' : '거짓'}`}</p> {/* 조건이 참일 경우 '참' 반환 */}
            <p>{`false ? '참' : '거짓' = ${false ? '참' : '거짓'}`}</p> {/* 조건이 거짓일 경우 '거짓' 반환 */}
        </div>
    )
}

export default Operator

- 전개 연산자

전개 연산자는 배열이나 객체를 복사하거나 합칠 때 사용됩니다. 배열의 경우 배열 내부의 요소를 추출하거나, 객체의 경우 객체 내부의 속성을 추출할 때 사용합니다.

  • ... : 전개 연산자
function Operator() {
    const array1 = [1, 2, 3]
    const array2 = [4, 5, 6]

    const array3 = [...array1, ...array2]

    const object1 = {
        a: 1,
        b: 2,
    }
    const object2 = {
        c: 3,
        d: 4,
    }

    const object3 = { ...object1, ...object2 }

    return (
        <div>
            <h2>전개 연산자</h2>
            <p>{`[1, 2, 3] + [4, 5, 6] = ${array3}`}</p>
            <p>{`{a: 1, b: 2} + {c: 3, d: 4} = ${JSON.stringify(object3)}`}</p>{' '}
            {/* JSON.stringify() : 객체를 문자열로 변환 */}
        </div>
    )
}

export default Operator

4. 함수

리액트에서 함수는 컴포넌트의 생명주기 함수, 이벤트 처리 함수, 상태 업데이트 함수 등 다양한 용도로 사용됩니다. 이번 장에서는 리액트에서 사용되는 주요 함수들을 알아보고, 각 함수의 사용법과 활용 방법을 살펴보겠습니다.

- 화살표 함수

화살표 함수는 ES6에서 도입된 새로운 함수 선언 방식으로, 함수를 간결하게 정의할 수 있습니다. 함수를 선언할 때 function 키워드 대신 => 기호를 사용하여 함수를 정의합니다.

// 함수 선언식
function Func1() {
    return (
        <div>
            <h1>안녕 난 리액트야!</h1>
            <p>리액트는 재밌어.</p>
        </div>
    )
}

// 화살표 함수
const Func2 = () => {
    return (
        <div>
            <h1>안녕 난 리액트야!</h1>
            <p>리액트는 재밌어.</p>
        </div>
    )
}

function Func() {
    return (
        <div>
            <Func1 />
            <Func2 />
        </div>
    )
}

- 화살표 함수 & 반환값

화살표 함수는 return 키워드를 생략할 수 있습니다. 함수 내부의 코드가 한 줄로 표현 가능할 때는 중괄호를 생략하고, 바로 반환할 수 있습니다.

const Func1 = () => (
    <div>
        <h1>안녕 난 리액트야!</h1>
        <p>리액트는 재밌어.</p>
    </div>
)

const Func2 = () => (
    <div>
        <h1>안녕 난 리액트야!</h1>
        <p>리액트는 재밌어.</p>
    </div>
)

function Func() {
    return (
        <div>
            <Func1 />
            <Func2 />
        </div>
    )
}

- 화살표 함수 & 매개변수

화살표 함수는 매개변수를 받아서 처리할 수 있습니다. 매개변수가 하나일 때는 괄호를 생략할 수 있으며, 매개변수가 없을 때는 괄호를 생략할 수 없습니다.

const Func1 = (name, desc) => {
    return (
        <div>
            <h1>안녕 난 {name}야!</h1>
            <p>
                {name}는 {desc}.
            </p>
        </div>
    )
}

const Func2 = () => {
    return (
        <div>
            <h1>안녕 난 리액트야!</h1>
            <p>리액트는 재밌어.</p>
        </div>
    )
}

function Func() {
    return (
        <div>
            <Func1 name="리액트" desc="재밌어" />
            <Func2 />
        </div>
    )
}

- 비구조화 할당 (Destructuring Assignment)

비구조화 할당은 ES6(ECMAScript 2015)에서 도입된 기능으로, 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 해줍니다. 함수의 매개변수로 객체를 전달할 때, 비구조화 할당을 사용하여 속성을 추출할 수 있습니다.

const Func1 = (props) => {
    // props = { name: '리액트', desc: '재밌어' }

    return (
        <div>
            <h1>안녕 난 {props.name}야!</h1>
            <p>
                {props.name}는 {props.desc}.
            </p>
        </div>
    )
}

function Func() {
    return (
        <div>
            <Func1 name="리액트" desc="재밌어" />
        </div>
    )
}

비구조화 할당을 사용하여 속성을 추출할 수 있습니다.

const Func1 = (props) => {
    const { name, desc } = props

    return (
        <div>
            <h1>안녕 난 {name}야!</h1>
            <p>
                {name}는 {desc}.
            </p>
        </div>
    )
}

function Func() {
    return (
        <div>
            <Func1 name="리액트" desc="재밌어" />
        </div>
    )
}

비구조화 할당을 사용하여 속성을 추출할 수 있습니다.

const Func1 = ({ name, desc }) => {
    return (
        <div>
            <h1>안녕 난 {name}야!</h1>
            <p>
                {name}는 {desc}.
            </p>
        </div>
    )
}

function Func() {
    return (
        <div>
            <Func1 name="리액트" desc="재밌어" />
        </div>
    )
}

- 함수의 전개 연산자

함수의 전개 연산자를 사용하여 객체나 배열을 전달할 수 있습니다. 함수의 매개변수로 객체나 배열을 전달할 때 전개 연산자를 사용하여 속성을 추출할 수 있습니다.

const Func7 = ({ name, desc }) => {
    return (
        <div>
            <h1>안녕 난 {name}야!</h1>
            <p>
                {name}는 {desc}.
            </p>
        </div>
    )
}

function Func() {
    const data = {
        name: '리액트',
        desc: '재밌어',
    }

    return (
        <div>
            <Func7 {...data} />
        </div>
    )
}

기본값 (Default Value)

매개변수에 기본값을 설정할 수 있습니다. 매개변수가 전달되지 않았을 때 기본값으로 설정된 값이 사용됩니다.

const Func1 = ({ name = '리액트', desc = '재밌어' }) => {
    return (
        <div>
            <h1>안녕 난 {name}야!</h1>
            <p>
                {name}는 {desc}.
            </p>
        </div>
    )
}

function Func() {
    return (
        <div>
            <Func1 />
        </div>
    )
}

정답을 확인해보세요.

정답 1.

import React from 'react'

// 사용자의 로그인 상태를 표시하는 리액트 컴포넌트
function UserStatus() {
    const isLogged = true // 로그인 상태를 나타내는 변수 (true 또는 false)

    return (
        <div>
            {/* isLoggedIn 값에 따라 조건부 렌더링 */}
            {isLogged ? <p>로그인</p> : <p>로그아웃</p>}
        </div>
    )
}

export default UserStatus
반응형
티스토리 친구하기