sm 기술 블로그

6강. state 본문

리액트

6강. state

sm_hope 2022. 8. 31. 11:47

State 는 리액트에서 앱의 유동적인 데이터를 다루기 위해 있는 객체이다.

 

따라서 State를 사용하면 자동으로 재랜더링 된다.

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

useState는 배열을 return하고 그 안의 값은 초깃값으로 생각하면 된다.

배열의 0번째는 상태의 값을 읽을때, 1번째는 그 상태의 값을 변경할 때 사용하는 함수이다.

따라서 useStated의 초기값은 'WELCOME'이고, 이 useState의 0번째는 'WELCOME'을 읽어오고 1번째는 변화가 되었을 때 작동한다.

이를 콘솔로 찍어보면

다음과 같다.

 

이 것을 함축하여 작성하면

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

다음과 같이 작성할 수 있다.

 

다시말해 useState는 재 랜더링 되도록 하고, setMode가 바뀌면 재 랜더링이 일어난다. 

import {useState} from 'react';

... 생략 ...

function App() {
  // const _mode = useState('WELCOME');
  // console.log("mode: ",mode);
  // console.log("setMode: ",setMode);

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

... 생략 ...

  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 className="App">
      <Header title = "WEB" onChangeMode={()=>{
        setMode('WELCOME');
      }}></Header>
      <Nav topics={topics} onChangeMode={(id)=>{
        setMode('READ');
      }}></Nav>
      {content}
    </div>
  );
}

export default App;

다음과 같이 진행되면

html, css, javascript a태그를 클릭했을 때 Read Hello,Read로 넘어가게 된다.

 


클릭한 태그에 따라서 내용을 다르게 하기

useState로 재랜더링 되는 것을 보았다.

이제 클릭한 태그에 따라 다른 내용으로 랜더링 되도록 해보자.

 

먼저 우리가 각 topics에 id와 title, body를 넣었다.

  ... 생략 ...
  const topics =  [
    {id:1 , title:'html', body:'html is ...'},
    {id:2 , title:'css', body:'css is ...'},
    {id:3 , title:'javascript', body:'javascript is ...'}
  ]
  ... 생략 ...

여기서 id에 따라 title과 body가 다르게 변하도록 해보자.

 

... 생략 ...

function Nav(props){

  const tmp = props.topics;
  const lis = tmp.map((tmp) => <li key={tmp.id}> <a id={tmp.id} href={'/read/' + tmp.id} onClick={event=>{
    event.preventDefault();
    props.onChangeMode(Number(event.target.id));
  }}>{tmp.title}</a></li>);

  return <nav>
  <ol>
    {lis}
  </ol>
</nav>
}

... 생략 ...

function App() {
  // const _mode = useState('WELCOME');
  // console.log("mode: ",mode);
  // console.log("setMode: ",setMode);

  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 className="App">
      <Header title = "WEB" onChangeMode={()=>{
        setMode('WELCOME');
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id)=>{
        setMode('READ');
        setId(_id);
      }}></Nav>
      {content}
    </div>
  );
}

export default App;

전에 제목(WEB)을 누르는 것이 아니면 값은 READ를 갖게 만들었다.

그러면 useState의 mode 부분이 READ로 바뀌면서 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;
      }

 

다음 코드를 추가 시켜준다.

 

그러면 해당 id에 따라 title과 body를 값을 받는데 이 id가 어디서 나오는지 알아 보겠다.

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

useState를 통해 id를 정의 해주었다.

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

html css javascript 태그 중 하나를 클릭하면 mode가 READ를 저장하고 상위컴포넌트에서 정의된 id를 _id로 가져와 setId로 변화를 준다.

 

이 id가 뭔지 아는 이유는 

function Nav(props){

  const tmp = props.topics;
  const lis = tmp.map((tmp) => <li key={tmp.id}> <a id={tmp.id} href={'/read/' + tmp.id} onClick={event=>{
    event.preventDefault();
    props.onChangeMode(Number(event.target.id));
  }}>{tmp.title}</a></li>);

  return <nav>
  <ol>
    {lis}
  </ol>
</nav>
}

Nav함수에서 prpos로 받은 값(topics)을 map으로 각 태그를 만들어 주어 그려주었다.

때문에 각 태그들은 고유한 id를 가지며, 그 id는 처음에는 정수형이었으나 event.target.id로 인해 문자열로 변하고, Number로 다시 정수로 형변환을 해준 덕분에 정수형임을 알 수 있게 된 것이다.

 

그러면 해당 topcis의 title과 body를 추출할 수 있게 된다.

https://github.com/denist2322/youtube_react/commit/8fc814a132227399c19ac050fdb00fa5f06ec569

 

6강 state · denist2322/youtube_react@8fc814a

Showing 1 changed file with 29 additions and 5 deletions.

github.com

 

'리액트' 카테고리의 다른 글

8강. Update  (0) 2022.08.31
7강. Create  (0) 2022.08.31
5강. 이벤트  (0) 2022.08.30
4강. props  (0) 2022.08.30
3강. 컴포넌트 만들기  (0) 2022.08.29
Comments