Daehyunii's Dev-blog

[데브코스] TIL-124 React, 컴포넌트, useEffect, useRef, props 본문

✏️ 2022. TIL/December (데브코스)

[데브코스] TIL-124 React, 컴포넌트, useEffect, useRef, props

Daehyunii 2022. 12. 17. 22:15
React란?

1. React 소개

  리액트는 라이브러리이다. 리액트를 구성하는 기능들은 최소한의 노력으로 최대의 효율을 내기 위함이다.

2. React 특징

  • Reactive Programming이다.
    • React는 상태를 관찰하고 변화가 발생할 경우 연관된 곳에서 연산이 수행된다.
  • MVC에서 리액트는 V만 관리한다. 여기서 View는 컴포넌트이다. 컴포넌트는 재사용이 가능한 독립적인 객체이며 런타임 시점에 사용된다.
    • 컴포넌트는 트리 구조로 나타낼 수 있다.
    • 컴포넌트 조합으로 View를 구성한다.
  • Virtual DOM이다.
    • 필요한 부분만 한 번에 렌더링한다.
    • 성능보다는 개발을 쉽게 하기 위해 사용되었다.

2. create-react-app, JSX

2.1 create-react-app

  새로운 리액트 앱을 만들기 쉽게 도와준다.

npx create-react-app [app이름]

2.2 JSX

  자바스크립트에 XML을 추가하여 확장한 문법이다. UI가 어떻게 생겨야 하는지 설명하기 위해 React와 함께 사용할 것을 권장한다.

  • 자바스크립트에서 이미 class가 예약어이기 때문에 HTML의 class부분에 className을 사용해야한다.
  • 최상위가 하나여야 한다.
  • 표현식이나 조건문도 넣을 수 있다. 중괄호 내부에 작성하면 된다.

3. 컴포넌트

  리액트의 컴포넌트는 함수이다. UI를 추상적으로 바라보고 공통점을 찾아 컴포넌트를 만들면 재사용할 수 있는 컴포넌트를 만들 수 있다. 컴포넌트에서 데이터는 단방향으로 전달된다.

4. Props

  props를 사용하여 부모 컴포넌트에서 자식 컴포넌트에게 데이터를 넘겨줄 수 있다.

// props.size => 구조분해할당
function Button({ size = 30 }) {
    return (
        <button style={ width: size }></button>
    )
}
import Button from './Button.js'

function App() {
    return (
        ...
        <Button size={50} />
    )
}

4.1 children

propschildren을 사용하면 자식 컴포넌트 태그 내부의 내용이 children에 전달된다.

function Paragraph({ children }) {
    return (
        <p>{ children }</p>
    )
}
import Paragraph from './Paragraph.js'

function App() {
    return (
        ...
        <Paragraph>
            <code>App.js</code> is running.
        </Paragraph>
    )
}

분기와 반복

1. 분기

  상태 값이 true인지 false인지에 따라 요소를 보여줄지 말지를 나타낼 수 있다. 논리곱(&&)을 사용하거나 삼항연산자를 사용하면 된다.

2. 반복

  map이나 filter 등의 고차함수를 사용하여 요소를 반복해줄 수 있다. map을 사용할 때는 꼭 요소에 key 값을 넣어주어야 한다.


이벤트 바인딩, 리액트 훅

1. 컴포넌트에서 지역 상태 관리하는 법

  useState()를 사용하여 지역 상태를 관리할 수 있다. 아래에서 count가 상태이고, setCount가 상태 값을 변경할 수 있는 함수를 나타낸다.

const [count, setCount] = useState(0)

2. 컴포넌트에 이벤트 바인딩하기

  이벤트를 처리할 함수를 만들어서 요소의 이벤트에 바인딩해주면 된다.

...

const handleIncrease = () => {
    setCount(count + 1)
}

return (
    ...
    <button onClick={handleIncrease}>+</button>
)

3. 부모 컴포넌트에게 메세지 전달하기

  props를 통해 전달해줄 수 있다. 아래에서는 props로 함수를 넘겨주는 것을 확인해보자.

function Counter({ onChange }) {

    const handleIncrease = () => {
        setCount(count + 1)
        if (onChange) onChange(count + 1)
    }

    return (
        ...
        <button onClick={handleIncrease}>+</button>
    )
}

4. useEffect

  무언가 변화가 있을 때 감지하여 반응하는 hook이다. useEffect는 컴포넌트가 처음 로드될 때 실행된다. 상태 변화를 감지하거나 전역적인 이벤트를 사용할 때 쓸 수 있다. return으로 반환된 함수는 컴포넌트가 제거될 때 실행된다.

5. useRef

  DOM에 직접 접근할 때 사용하거나 지역 변수로 사용할 때 사용할 수 있다. 여기서 지역 변수로 사용하는 것은 useState로도 할 수 있지만 큰 차이가 있다.

  • useState는 값이 변경될 때 다시 렌더링을 한다.
  • useRef는 값이 변경되어도 다시 렌더링하지 않는다.

 

오늘을 마무리 하며

 

  오늘부터 데브코스의 리액트 강의가 시작되었다. Vue에서 겪었던 혼란이 있기 때문에 리액트 강의를 듣기 전에 우선 어느 정도 기본기는 익혀두는것이 도움이 될 것 이라는 판단이 들어 인프런 제로초님의 강의를 선수강하고 듣기 시작했다. Vue에서 한 번 겪어봐서 그런지 오히려 리액트 코드들을 처음 접하는 순간부터 많은 이질감이 들지는 않았고, 제로초님의 강의를 선수강하면서 코드의 흐름들을 충분히 숙지할 수 있었다. 그래서 코드 작성에 아직 완전히 익숙한 상태는 아니지만 어느 정도 친근해진 느낌이 강하게 들었다. 우선 리액트를 공부하면서 느낀 첫 느낌은 재미있다!! 이 재미가 그 동안의 공부들의 효과로 조금은 쉽게 다가오게 된 것인지, 리액트 자체가 쉽기 때문인지는 솔직히 모르겠지만, 굉장히 편리하고 또 편리했다. 

  

  가장 마음에 들었던 개념은 state가 변경되면 다시 렌더링이 일어난다는 점이다. 그 전에는 항상 state의 변경이 있을때 많은 처리들이 부가적으로 필요했기 때문이다. 하지만 리액트는 state가 변경되면 다시 렌더링이 일어난다. 이게 가장 큰 편리함이라고 다가왔다. 그리고 상태관리를 위해 제공되는 useState는 굉장히 직관적이고 setState를 통해 값을 변경하는것 또한 굉장히 쉽게 다가왔다. 그치만 한 가지 걱정되는 부분 역시 state가 변경되면 리렌더링이 된다는 점이다. 성능상의 이슈가 없는지에 대한 의문이 들었다. 하지만 useRefuseEffectuseMemo, useCallback을 통해서 불필요한 리렌더링을 억제할 수 있는 hook들이 있다는것을 봤을 때, 성능상의 이슈를 최소화할 수 있는 것들이 존재할 거라고 믿고 또 문제는 없는지 알아보면서 계속 공부해 나가야겠다. 

 

(아직 가상돔에 대한 개념확립이 명확하게 되지 않아서 가상돔이 주는 이점에 대해서는 공부가 필요하겠다..)