리액트 컴포넌트, state

데브코스

목록 보기
81/131

컴포넌트

클래스형 컴포넌트와 함수형 컴포넌트가 있음.
클래스형이 초기에 많이 사용됐고, 현재는 함수형이 많이 권장됨.
가독성이나 코드 양 등에서 함수형이 더 좋음. 다만, 레거시 코드들 이해하려면 클래스형도 알아야 됨.

먼저 클래스형 컴포넌트는 이런 식으로 짜면 된다.

import { Component } from "react";

class ClassCom extends Component {
  render() {
    return <div>클래스형 컴포넌트</div>;
  }
}

export default ClassCom;

저렇게 class를 만들고, extends 키워드를 이용해서 Component를 상속받는다(Component import는 알아서 됨).
그러고 꼭 render() 함수 안에 이제 return()을 넣고, 그 안에 html 코드를 쭉 넣어주면 된다. 그러고 마지막으로 export default로 외부로 빼주면 된다.
이러면 이제 클래스형 컴포넌트 하나가 완성된 것이다.
이제 이렇게 만든 컴포넌트를 쓰고 싶으면, 해당 파일에서 ClassCom을 import 해오면 된다. 그리고 쓸 때는

<ClassCom></ClassCom>

이렇게 써주면 된다. 저렇게 하면 이제 저 자리에 아까 만든 컴포넌트가 들어가게 되는 것이다.

다음은 함수형 컴포넌트다. 함수형 컴포넌트는 아래와 같이 만들면 된다.

import React from "react";

function FuncCom() {
  return <div>함수형 컴포넌트</div>;
}

export default FuncCom;

일단 render 같은게 필요없고, 아무래도 클래스보다는 함수가 좀 더 간단하기 때문에, 결과적으로 클래스형 컴포넌트보다는 좀 더 쉽게 느껴진다.
그냥 함수 만들고 바로 return 하면 끝이다. import 문은 자동완성이 안되기 때문에 직접 추가 해줘야 된다는 점을 참고하자.
또한 export default도 빼먹지 말고 추가해줘야 한다. 사용방법은 클래스형 컴포넌트와 동일하므로 넘어가도록 하겠다.
추가로 만약에 arrow function 형태로 만들고 싶으면

const FuncCom = () => {~};

이렇게 해주면 된다.

추가로 하나만 더 알아보자. 우리가 이제 ts에서는 : type 형태로 type을 직접 지정해주었다. 우리가 위에서 만든 함수형 컴포넌트에도 지정해줄 수 있다.

const Test: React.FC = () => {~};

이렇게 해주면 된다. FC가 Function Component의 약자다. 그래서 이렇게 :React.FC를 붙여주면 된다.
명확성을 높여주고, 가독성을 올리기 위해 사용함.

State

state에 대해 알아보자. 내가 아는 부족한 지식에 의하면, React에서 가장 중요한 것 중 하나가 이 state다.
React의 장점 중 하나가 실시간성 보장, 그러니까 우리가 구현하면서 바로바로 재렌더링이 가능하다는 것인데, 그 때 이 state가 중요하다.
왜냐면 state 값은 동적 바인딩해서 사용할 때 값이 바뀌면 바로바로 재렌더링 되기 때문이다. 말로 하면 어려운데, 사용해보면 더 쉽게 감이 올 것이다.

const [todos] = useState("공부하기");

선언 자체는 이렇게 useState 이용해서 해주면 된다(useState 쓰면 import문이 자동완성이 된다).
만약에 안에 넣을 변수가 많다면 배열로 처리해주면 된다.

const [todos] = useState(["공부하기", "잠자기", "미팅하기"]);

이런식으로 말이다. 대신 당연하지만 사용할 때는 [] 이용해서 특정 인덱스에 접근하는 식으로 사용해야 된다.

또 중요한 것 중에서 하나가 state 변경 함수다. 보통 set을 붙이는걸 관례로 해서

const [todos, setTodos] = useState(["공부하기", "잠자기", "미팅하기"]);

이런 식으로 해주면 된다. 항상 state와 state 변경 함수까지 쌍으로 선언한다고 보면 된다.
state 값을 어디에서나 막 변경하지 않고, 마치 getter setter처럼 사용하기 위해서 존재하는 것이 state 변경 함수라고 보면 되겠다.

갑작스럽지만, 잠시 구조 분해 할당을 배우고 가보자.

const colors = ['red', 'green', 'blue'];
const [f, s, t] = colors;

이렇게 해주면 f, s, t에 각각 red, green, blue가 순서에 맞게 들어가게 된다. 이게 바로 구조 분해 할당이다. 분해돼서 각 멤버에 순서대로 들어가는 것이다.

근데 추가로 우리가 이제 저렇게 배열 형태의 값들을 바인딩해서 사용하다 보면

<ul>
  <li>{todos[0].text}</li>
  <li>{todos[1].text}</li>
  <li>{todos[2].text}</li>
</ul>

이런 식으로 되는 케이스가 굉장히 많을 것이다. 아무래도 배열의 값들을 모두 출력하다 보니 이렇게 되는 것이다.
근데 이게 지금 이렇게 두세개씩 있으면 괜찮은데, 만약에 배열 안에 값이 100개 있고 이걸 다 출력해야 되면? 이걸 하나하나 저렇게 하는건 진짜 오바다.
근데 그랬다고 for문 같은걸 막 쓸 수 있는 것도 아니다. 당연히 안된다. 그래서 이럴 때는 map을 써야 된다. 여기서 map은 자료형 map 말고, 함수 map이다.
사용방식은 아래와 같다.

<ul>
  {todos.map((todo, index) => (
    <li key={index}>{todo.text}</li>
  ))}
</ul>

일단 todos에 대해서 map을 돌리고, parameter에 값을 넣는데, 첫번째 값은 이제 순회했을 때 나오는 값, 그니까 배열 값 중 하나고, 두번째 값은 인덱스다.
그리고 괄호 열고 이제 원하는 코드를 넣으면 된다. 우리는 todos의 각 원소들의 text 값을 출력하려고 했으니까 그냥 todo.text를 출력하면 된다.
근데 li 옆에 보면 key가 있는데, 이건 그냥 관례적으로 넣는 것이다. 나중에 뭐 추적이라던지 이런 거 하기 위함인데, 보통 저렇게 그냥 index 값 부여해주면 된다.
만약에 뭐 원소에 id 값 같은게 따로 있으면 그거 넣어줘도 괜찮다.

예시

import React from "react";

const MapTest = () => {
  const fruits = ["apple", "banana", "orange"];
  return (
    <div>
      <h2>과일</h2>
      <ul>
        {fruits.map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
};

export default MapTest;

구조 분해 할당

 const colors = ['red', 'green', 'blue'];

위에 저 코드를 예를 들어

const [f, s, t] = colors;

라는 것에 받는다. 라고 생각을 해보자.
이것에 세개의 변수로 받으면 차례대로 f,s,t에 배열의 값들이 들어가게 될텐데,
f = red 이런식으로 들어가게 될텐데,

이게 구조 분해 할당이라는 거야.

배열 안에 있는 값들을 분해해서,
각각의 값마다 할당을 새롭게 해주면서 배열의 값을 가져올 수 있는 것이지.

const person = {
	name : 'lee',
    age : 20,
    city : 'seoul'
   };

이런 것들도 const {name, age, city} = person;
을 하게 되면 각각의 값에 저 person의 값들이 들어가게 될 거야.


취소선

태그를 이용하면 해당하는 것에 대한 취소선이 그어진다.

profile
Dive Head First | Work Super Hard | Attract Great People

0개의 댓글