[React]state와 props

sujin·2022년 9월 11일
0

React

목록 보기
7/16
post-thumbnail

드디어 리액트에서 가장 중요하고 가장 많이 쓰이는 state와 props개념에 대해서 정리해보려고 한다.
개념 자체는 그렇게 복잡하지 않았지만 배우고 나서 그래서 뭐 어쩌라고...? 🤷🏻‍♀️ 라는 생각이 들며 이 녀석들을 어떻게 활용해야할지 감이 잘 잡히지 않았다.
하지만...!! 한번 보고 다 알면 세상 사람들 다 개발자 했겠지..? 라는 생각을 하면서 나 자신을 위로하고 정신을 다시 바짝 차려서 state와 props의 개념을 정리하고 간단한 예제들도 살펴보고자 한다!


Hook

리액트 컴포넌트에 대해서 소개하면 함수 컴포넌트에서도 Hook의 등장으로 state나 lifeCycle등의 기능을 쓸 수 있다고 했다.

다시한번 정리하자면, Hook이란?

  • 클래스 컴포넌트에서만 사용할 수 있었던 상태 관리, 라이프 사이클 관리 기능을 함수 컴포넌트에서도 사용할 수 있도록 연동 시킨 것이다.
  • hook에는 여러 종류(useState useEffect useNavigate useRef 등)가 있으며 이런 hook들을 모음을 hooks 라고 한다.

특징

  • 함수 컴포넌트에서만 사용이 가능하다.
  • 이름은 반드시 use 로 시작한다.
  • 내장 hook이 존재한다. (useState useEffect)
  • 직접 hook을 만들어 쓸 수 있다. custom hook

사용 규칙

  • hook은 함수 컴포넌트 혹은 custom hook안에서만 호출할 수 있다.
  • 함수 컴포넌트 최상위에 위치
    • 최상위란 함수 컴포넌트의 첫 번째 중괄호 내부를 말한다.
  • return 아래에서는 호출할 수 없다.
  • 중첩할 수 없다. (반복문, 함수 선언문 등 안에서 쓸 수 없음)

💡 custom hook

  • 컴포넌트 내에서 훅을 사용해 로직을 구현하다 보면 중복되는 부분이 발생하는데 이런 중복되는 훅들을 결합하고 추상화하고자하는 니즈가 발생한다. 이때 custom hook을 만들어 사용할 수 있다.
  • custom hook은 Hook을 추상화된 로직으로 사용할 수 있도록 결합해주고 다른 컴포넌트 사이에서 공통의 상태 관련 로직을 재사용할 수 있도록 해준다.
    공식문서 참고

Props

  • properties의 약자로 컴포넌트의 속성값 을 나타낸다.
  • props는 컴포넌트에서 컴포넌트로 전달하는 데이터다.
  • props는 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서만 설정 가능함으로, prop의 값은 컴포넌트 내부에서 변경할 수 없다.

Props 지정하기

  • props는 <ComponentName prop1={propValue1} prop2={propValue2} ... /> 형태로 컴포넌트를 부를 때 함께 지정한다.
<Dog name="Ari" age={10} />
<Dog name="Bori" age={7} />
  • 같은 타입의 컴포넌트에 다른 props 값을 주어, 패턴이 반복되는 형태로 컴포넌트의 효율적인 재사용이 가능하다.
  • props에는 불리언 값(true, false), 숫자, 배열과 같은 다양한 형태의 데이터를 담을 수 있다. 공백 구분으로 여러 개를 담는 것도 가능하다.
  • props에 있는 데이터는 문자열인 경우를 제외하면 모두 중괄호{}로 값을 감싸야 한다.

Props 사용하기

  • props는 읽기 전용이므로 컴포넌트의 내부에서 props를 수정해서는 안 된다.
    • 만약 변경하고 싶다면, 컴포넌트 내부에서 state를 다시 만들어야한다.
    • 컴포넌트에서 설정한 state값을 변경할 수 있다. (props로 넘겨 받은 값은 변경X, 억지로 변경시 error발생)
// <객체 인자를 통해 props 받아오기>

function Dog(props) {
  consol.log(props)
  //결과
  //{name:'Ari', age:10}
  //{name:'Bori', age:7}
  
	return {
		<div>{props.name}</div>
		<div>{props.age}</div>
	}
}
  • props를 받는 함수형 컴포넌트에 인자를 정의하면, props를 속성으로 가지는 객체 Object가 해당 인자로 전달된다.
  • 컴포넌트 내부에서 사용 시, 객체에 존재하는 값을 가져오듯 점 연산자(.)를 사용하여 원하는 props를 꺼내 쓸 수 있고, 이를 중괄호로 감싸 { [인자 이름].[props 이름] } 형태로 사용한다.

State

  • 컴포넌트가 갖고 있는 상태값 이다.
  • 속성값이 변하면 리액트는 자동으로 UI를 변화시킨다.
  • state는 컴포넌트 내부의 동적 데이터를 의미한다.
  • 컴포넌트 내에서 정의하고 사용하며 얼마든지 변경할 수 있다.
  • useState라는 리액트 내장 훅을 사용한다.

useState

  • import {useState} from 'react' 로 import해야 사용이 가능하다.

  • 배열로 반환한다.
    const [name, setName] = useState();

    • 배열구조분해를 사용한다.
    • name
      • state(변수명)으로 동적으로 관리하고 하는 값을 할당 할 수 있다.
    • setName
      • state를 변경해주는 함수로 state를 업데이트 할 수 있다.
    • useState(초기값)
  • 동일한 컴포넌트 안에 있더라고 state는 각각 관리된다.(다른 state에 영향을 미치지 않는다.)

import { useState } from 'react'; 

const Hello = () => {
    const [name, nameChange] = useState('asj');

    function chageName() {
        const newName = name === 'asj' ? 'hdh' : 'asj';
        nameChange(newName);
     }

    return (
        <div>
            <span>State</span>
            <p>{name}</p>
            <button onClick = {chageName}>Chane Name</button>
        </div>
    )
}

export default Hello;

useState를 통해서 바뀌는 값 관리하기

react에서는 유동적인 데이터를 저장하기 위해서 state를 이용한다. state는 동적인 값 을 의미하는데, 직접 조작해서는 안되고 setState를 이용 해야한다.
왜냐하면 react는 state의 값이 변경되면 리렌더링을 해주는데 이때 setState를 이용하지 않고 직접 바꾸게 되면 react가 변경된 state를 감지하지 못하기 때문 이다.

//useState 기본구조

import {useState} from 'react';

const [state, setState] = useState('');

이벤트 설정

클릭 이벤트가 발생하면 counter되는 이벤트를 만들어보자.

//App.js

import React from 'react';
import Counter from './Counter';

const App = () => {
  return (
    <Counter />
  );
}

export default App;

//Counter.js

import React from 'react';

const Counter = () => {
 
 function OnIncrease() {
  console.log('+1');
 }
 function OnDecrease() {
  console.log('-1');
 }
 
  return (
    <div>
      <h1>0</h1>
      <button onClick={OnIncrease}>+1</button>
      <button onClick={OnDecrease}>-1</button>
    </div>
  );
}

export default Counter;
  • 증가 이벤트는 함수 OnIncrease에 설정을 해주었고, 감소 이벤트는 함수 OnDecrease에 설정해주었다.
  • 만들어진 함수는 각각 button 의 onClick 으로 각 함수를 연결해주었다. 리액트에서 엘리먼트에 이벤트를 설정해줄때에는 on이벤트이름={실행하고싶은함수} 형태로 설정해주어야 한다.

    ❗️ 주의할 점
    이벤트 함수를 onClick={onIncrease()} 이렇게 실행시키면안된다는 점이다. 이렇게 호출을 해주면 이벤트가 랜더링 되는 시점에 함수가 실행되기 때문에, (함수가 실행되면 리렌더링이 진행되되고 다시 함수가 실행되는 현상이 발생, state가 변경이 무한을 발생할 수 있음) 이벤트를 실행시킬때는 함수 타입의 값을 넣어주어야한다.


useState 사용

이제 위에서 설정한 이벤트의 동적인 값을 state를 이용하여 상태관리가 될 수 있도록 작성해 보려고 한다.

//Counter.js

import React, { useState } from 'react';

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

  const onIncrease = () => {
    setNumber(number + 1);
  }

  const onDecrease = () => {
    setNumber(number - 1);
  }

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;
  • import React, { useState } from 'react';

    • 리액트 패키지에서 useState 를 불러온다.
  • const [number, setNumber] = useState(0);

    • useState 를 사용 할 때에는 상태의 기본값을 파라미터로 넣어서 호출해준다.
    • useState는 배열을 반환하는데, 여기서 첫번째 원소는 현재 상태(number), 두번째 원소는 state를 변경해주는 함수(setNumber)이다.
  • 원래는 아래와 같이 해야하지만 배열구조분해 를 사용하여 각 원소를 추출해준 것이다.


const numberState = useState(0);
const number = numberState[0];
const setNumber = numberState[1];
  • <h1>{number}</h1>
    • <h1>안에 는 0이 아니라 {number}를 넣어주면 되는데 이는 state를 변경해주는 함수(setNumber)에서 전달받은 최신 값을 반영해 준다.

마무리✨

props와 state의 개념에 대해서 간단히 정리해 보았는데, 개념은 이해가 가지만 어떻게 활용할지는 직접 예제들을 접하고 간단한 프로젝트라고 만들어 보면서 해봐야 자연스럽게 쓸 수 있을 것 같다!
역시 코드는 손으로 직접 쳐보고 결과를 눈으로 직접 확인해봐야 이해가 잘 가는 것 같다~~

profile
개발댕발

0개의 댓글