본문 바로가기
Web framework/React

React State

by Tarake 2024. 12. 25.

서론

2024.12.24 - [Web framework/React] - React 이벤트

 

React 이벤트

서론2024.12.23 - [Web framework/React] - React Prop React Prop서론2024.12.22 - [Web framework/React] - React 컴포넌트 (Component) React 컴포넌트 (Component)서론2024.12.21 - [Web framework/React] - React 시작하기 React 시작하기서

hosunghyun.tistory.com

이전 글까지는 React의 이벤트에 대해서 학습하고 실습했습니다. 이번 글에서는 React의 State에 대해서 학습해보고자 합니다.

 

State 란?

State는 React 컴포넌트에서  동적 데이터를 관리하기 위해 사용되는 객체입니다. state가 변경되면 해당 컴포넌트는 자동으로 리렌더링 됩니다.

 

컴포넌트에는 입력과 출력이 존재합니다. 입력으로는 prop이 있고 출력으로는 return이 존재합니다. 해당 return 값이 새로운 UI가 됩니다.

 

prop과 함께 컴포넌트 함수를 다시 실행해서 새로운 return 값을 만드는 데이터를 state라고 합니다. prop과 state의 차이점은 prop은 외부자를 위한 것이라면 state는 내부자를 위한 것입니다.

State의 특징

  • 동적 데이터 관리 : 사용자의 입력, API 응답 등 변경 가능한 데이터를 저장합니다.
  • 컴포넌트 내에서만 접근 가능 : state는 해당 컴포넌트에서만 접근하고 수정할 수 있습니다.
  • 비동기적으로 엡데이트 : state 업데이트는 비동기적으로 처리됩니다.
  • state 변경시 리렌더링 발생 : state가 변경되면 해당 컴포넌트와 하위 컴포넌트가 다시 렌더링 됩니다.
  • Immutable (불변성 유지) : state를 직접 변경하지 않고 setState나 useState를 통해 새로운 값을 할당해야 합니다.

 

State 실습하기

function App() {
  const mode = 'WELCOME';
  const lis = [
    {id : 1, title : "html", body : "html is"},
    {id : 2, title : "css", body : "css is"},
    {id : 3, title : "javascript", body : "javascript is"}
  ]
  let content = null;
  if(mode === 'WELCOME') {
    content = <Article title="Welcome" body="Hello, WEB"></Article>
  }
  else if (mode === 'READ') {
    content = <Article title="Read" body="Hello, Read"></Article>
  }
  return (
    <div>
      <Header title="React" onChangeMode={()=>{
        mode = 'WELCOME';
      }}></Header>
      <Nav lis={lis} onChangeMode={(id)=>{
        mode = 'READ';
      }}></Nav>
      {content}
    </div>
  );
}

코드를 이런식으로 작성했다고 치면 const mode = '' 부분을 바꾸면 UI가 변경되지만 클릭했을 때 변경되는 동작은 실행되지 않습니다.

 

왜냐하면 mode 값은 변경되어도 App() 함수는 다시 실행되지 않기 때문에 변화가 없습니다. 이 때 사용되는 것이 state입니다.

 

state를 사용하기 위해서는 훅을 사용해야 합니다.

import {useState} from 'react';

훅은 react에서 기본적으로 제공하는 함수입니다.

 

mode는 지역 변수인데 이를 상태로 업그레이드를 해야 합니다.

const _mode = useState('WELCOME');

이런식으로 작성하면 상태가 return 되는데 해당 값을 _mode에 저장합니다.

 

이 값을 콘솔창에 출력해 보겠습니다.

console.log("_mode", _mode);

0번째 값은 useState를 선언할 때 값입니다. 1번째 값은 함수입니다.

 

여기서 0번째 값은 state의 상태값을 읽을 때 쓰이고 1번째 값은 해당 값을 변경할 때 사용되는 함수입니다. 

const mode = _mode[0];
const setMode = _mode[1];

이런 식으로 작성하면 mode를 통해서 값을 불러올 수 있고 setMode를 통해서 값을 변경할 수 있다는 규칙이 생기게 됩니다. 

 

위에 코드들을 작성하면 3줄을 차지하기 때문에 가독성이 떨어지므로 아래와 같이 축약해서 작성할 수 있습니다.

const [mode, setMode] = useState('WELCOME');

 

작성된 코드는 다음과 같습니다.

function App() {
  const [mode, setMode] = useState('WELCOME');
  const lis = [
    {id : 1, title : "html", body : "html is"},
    {id : 2, title : "css", body : "css is"},
    {id : 3, title : "javascript", body : "javascript is"}
  ]
  let content = null;
  if(mode === 'WELCOME') {
    content = <Article title="Welcome" body="Hello, WEB"></Article>
  }
  else if (mode === 'READ') {
    content = <Article title="Read" body="Hello, Read"></Article>
  }
  return (
    <div>
      <Header title="React" onChangeMode={()=>{
        setMode('WELCOME');
      }}></Header>
      <Nav lis={lis} onChangeMode={(id)=>{
        setMode('READ');
      }}></Nav>
      {content}
    </div>
  );
}

 

실제로 동작시킨 모습은 다음 이미지와 같습니다.

이전과 달리 실제로 클릭하면 컴포넌트가 변경된 것을 확인할 수 있습니다.

 

즉 App()이 이전과 달리 재실행 되기 때문에 mode가 Read 변경된 내용을 적용할 수 있게 되었습니다. 

 

Nav 클릭 시 변경되게 실습하기

이번에 실습할 내용은 클릭한 내용에 따라 state가 변경되게 학습하고자 합니다.

const [id, setId] = useState(null);

일단 App() 함수 안에 다음과 같이 state를 작성해 줍니다.

 

이제 Nav를 클릭했을 때 값이 설정되도록 작성하면 됩니다.

<Nav lis={lis} onChangeMode={(_id)=>{
    setId(_id);
    setMode('READ');
}}></Nav>

위 와 같이 코드를 작성하면 이제 Nav를 클릭하면 해당 Nav 값의 id를 매개변수로 전달해서 App() 함수가 다시 실행되게 됩니다. 이제 Article이 변경되게 코드를 작성하면 됩니다.

 

전체 코드는 다음과 같습니다.

function App() {
  const [mode, setMode] = useState('WELCOME');
  const [id, setId] = useState(null);
  const lis = [
    {id : 1, title : "html", body : "html is"},
    {id : 2, title : "css", body : "css is"},
    {id : 3, title : "javascript", body : "javascript is"}
  ]
  let content = null;
  if(mode === 'WELCOME') {
    content = <Article title="Welcome" body="Hello, WEB"></Article>
  }
  else if (mode === 'READ') {
    let title, body = null;
    for(let i = 0; i < lis.length; i++) {
      if(lis[i].id === id) {
        title = lis[i].title;
        body = lis[i].body;
      }
    }
    content = <Article title={title} body={body}></Article>
  }
  return (
    <div>
      <Header title="React" onChangeMode={()=>{
        setMode('WELCOME');
      }}></Header>
      <Nav lis={lis} onChangeMode={(_id)=>{
        setId(_id);
        setMode('READ');
      }}></Nav>
      {content}
    </div>
  );
}

id 값을 전달 받았기 때문에 id에 맞는 lis를 찾는 반복문을 작성했습니다. lis의 id와 state로 들어온 id가 맞다면 사용자가 클릭한 id 이므로 해당 title과 body를 Article의 props로 전달하면 됩니다. 하지만 코드를 이대로 작성하면 문제가 발생합니다.

 

if(lis[i[.id === id) 이 부분에서 오류가 발생하는데 이유는 서로 자료형이 다르기 때문입니다. String과 int 값으로 비교가 되지 않기 때문에 자료형을 맞춰줘야 합니다. 저는 이때 매번 반복문 때마다 형변환 하는 것보다 lis의 id의 값을 변경해 주었습니다.

props.onChangeMode(Number(event.target.id));

Nav 컴포넌트 안에서 lis의 id를 정수형으로 변경하여 React가 동작하도록 변경하였습니다.

'Web framework > React' 카테고리의 다른 글

React Update  (0) 2024.12.28
React Create  (0) 2024.12.27
React 이벤트  (0) 2024.12.24
React Prop  (0) 2024.12.23
React 컴포넌트 (Component)  (0) 2024.12.22