C-log

⚛️React : section07 - state 본문

⚛️React/⚡ver.0

⚛️React : section07 - state

4:Bee 2024. 1. 12. 18:29
728x90

이번 시간에 우리는 state를 배우게 되었다. 우선 state가 필요한 이유를 설명하기 위해 아래 코드를 먼저 살펴보자

function App() {
  
  const mode = 'WELCOME'//event가 발생 했을 때 변경되는 변수 값

  const topics = [
    { id: 1, title: 'html', body: 'html is..' },
    { id: 2, title: 'css', body: 'css is..' },
    { id: 3, title: 'javascript', body: 'javascript is..' }
  ]
  return (
    <div>
 
      <Header title="WEB" onChangeMode={() => {
        mode = 'WELCOME';
      }}></Header>
 
      <Nav topics={topics} onChangeMode={(_id) => {
        mode = 'READ';
      }}></Nav>
 
    </div >
  );
}
export default App;  //contact App_7.js

해당 코드의 컴포넌트들을 각기 연관지어서 설명을 하자면 Header컴포넌트가 눌렸을 때 mode는 WELCOME이 되어야 하고 Nav 컴포넌트가 눌리면 mode는 READ가 되는 것이다. 하지만 실제로 동작은 그렇지 못하다. 짐작으론 현재 우리가 보고 있는 스크립트는 App_7 또는 index.js와 import 되어 있다. 이는 곧 의존관계인 것이고 해당 코드가 한번 파싱이 된다는 것이다. 즉, 지속적으로 파싱 또는 랜더링이 되지 않는 것이다. 그래서 js에서도 지속적으로 상태를 확인하고 변동해야하 할 때 setTimeout을 사용하는 경우가 있다. 그래서 React에서는 이를 해결하기 위해 useState라는 모듈을 사용한다. 이를 변경한 코드를 보기 전에 useState를 잠깐 보면 아래와 같다.

 
const _mode = useState('WELCOME'
const mode = _mode[0];
const setMode = mode[1];
 

useState는 인자를 두가지를 가진다. 첫 번째 인자로는 기본값 상태이고 두 번째는 상태를 변경할 수 있는 함수이다. 위와같이 표기하는 방법도 있지만 이를 한번에 처리 할 수 있는 방법이 있다. 바로 배열 비구조화 할당을 사용하는 것이다. 코드는 아래와 같다.

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

이와 같이 작성하고 이를 이용해서 상태를 변경할 것이다. 이제 App 컴포넌트를 변경하면 아래와 같다.

  ...
return (
    <div>
      <Header title="WEB" onChangeMode={() => {
        setMode('WELCOME')
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id) => {
        setMode('READ')
      }}></Nav>
    </div >
  );
  ...

이렇게 작성하면 이제 브라우저에서도 잘 작되는 모습을 볼 수 있다. 이를 응용해서 코드를 마저 작성하면 아래와 같다.

function App() {
  const [mode, setMode] = useState('WELCOME');
  const [id, setId] = useState(null);

  const topics = [
    { 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 < topics.length; i++) {
      if (topics[i].id === id) {
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Article title={title} body={body} ></Article>
  }
  return (
    <div>
      <Header title="WEB" onChangeMode={() => {
         setMode('WELCOME')
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id) => {
        setMode('READ')
        setId(_id);
      }}></Nav>
      {content}
    </div >
  );
}
export default App;

기존에 있는 Article 컴포넌트를 핸들링 할 수 있게 content변수에 담을 수 있게 했고 이를 Header컴포넌트와 Nav컴포넌트를 통해서 상태가 변경 되면 if문을 통해서 조건문이 실행 되고 두 번째 useState인 id를 setid(_id)인 props로 인가 받아 Article의 태그 속성들이 변경되는 논리로 이루어져 있다. 어떻게보면 단순하지만 하나하나 따져보면 굉장히 복잡하게 이루어져 있다. 잘만 정리한다면 어려움이 없을 것이다. 아래는 전체코드이다.

import { useState } from "react";

function Header(props) {
  return <header>
    <title>section04</title>
    <h1><a href="/" onClick={(event) => {
      event.preventDefault();
      props.onChangeMode();
    }}>{props.title}</a></h1>
  </header>
}
function Article(props) {
  return <article>
    <h2>{props.title}</h2>
    {props.body}
  </article>
}
function Nav(props) {
  const lis = []
  for (let i = 0; i < props.topics.length; i++) {
    let t = props.topics[i];
    lis.push(
      <li key={t.id}>
        <a id={t.id} href={'/read/' + t.id}
          onClick={(event) => {
            event.preventDefault();
            props.onChangeMode(Number(event.target.id)); //함수를 props로 호출해서 컨트롤 하는 것이다.
            //props.onChangeMode(t.id);
          }}
        >{t.title}</a></li>
    )
  }
  return <nav>
    <ol>
      {lis}
    </ol>
  </nav>

}
function App() {
  //첫번째 인자는 상태이고 두번째 인자는 상태를 변경하는 함수이다. WELCOME은 초기 값이다.
  // let _mode = useState('WELCOME') //event가 발생 했을 때 변경되는 변수 값
  // const mode = _mode[0];
  // const setMode = mode[1];
  const [mode, setMode] = useState('WELCOME'); //setMode로 변경된 값이 mode로 값이 전달
  const [id, setId] = useState(null);

  const topics = [
    { 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 < topics.length; i++) {
      if (topics[i].id === id) {
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Article title={title} body={body} ></Article>
  }
  return (
    <div>
      <Header title="WEB" onChangeMode={() => {
        // mode = 'WELCOME';
        setMode('WELCOME')
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id) => {
        setMode('READ')
        setId(_id);
      }}></Nav>
      {content}
    </div >
  );
}
export default App;  //contact App_7.js
728x90

'⚛️React > ⚡ver.0' 카테고리의 다른 글

⚛️React : section09 - Update  (0) 2024.01.15
⚛️React : section08 - Create  (0) 2024.01.14
⚛️React : section06 - Event  (0) 2024.01.11
⚛️React : section05 - props  (0) 2024.01.08
⚛️React : section04 - component  (0) 2024.01.08
Comments