본문 바로가기

React Native

React #5 - 표현컴포넌트, 리엑트훅

표현컴포넌트 & 컨테이너 컴포넌트 

 

 

[표현 컴포넌트 예시 - 상태를 관리하지 않는 컴포넌트] (부모)

import Header from "../../components/Header";
import Footer from "../../components/Footer";
import TodoContainer from "./TodoContainer";

function ListPage(){

  return (
    <div id="todo">
      <Header />
      <TodoContainer />
      <Footer />
    </div>
  );
}

export default ListPage;

 

 

 

[컴포넌트 컴포넌트 예시 ] (자식)

import {useState} from "react"
import { produce } from "immer";
import Todo from "./todo";


//컴포넌트들이 직접 상태관리를 하던 거를 표현 컴포넌트와 하위컴포넌트들에게 state를 전달해주는 식으로 변경하면 ~ ~

function TodoContainer(){
  // 샘플 목록
  const [itemList, setItemList] = useState([
    { _id: 1, title: '두부', done: true} ,
    { _id: 2, title: '계란', done: false },
    { _id: 3, title: '라면', done: true },
  ]);

  function addItem(item){
    // 데이터 갱신(상태 변경)
    const newItemList = [...itemList, item];
    setItemList([ ...itemList, item ]);

    // console.log(itemList, newItemList);
    //전개 복사를 사용했기 때문에 불변상태를 지킴
   
  }


  function toggleDone(_id){ //불변상태를 지키도록 수정이 필요하다.
    // 데이터 갱신(상태 변경)

    /* ------------------------------- 불변성 없는 CASE ------------------------------ */
    // const item = itemList.find(item => item._id === _id);
    // item.done = !item.done;

    /* ------------------------------- 불변성 있는 CASE ------------------------------ */

    // const newItemList = itemList.map(item => {
    //   if(item._id === _id){
    //     return {...item, done: !item.done}; // 기존 done 값에서 반전해서 반환
    //   }else {
    //     return item; // 변화 없이 리턴함
    //   }
    // })


    /* ----------------------------- immer를 사용한 CASE ---------------------------- */
   
    //아까 사용한 불변성 없는 CASE의 코드이지만, immer가 붙으면 달라진다.
    const newItemList = produce(itemList, draft => { //첫번째 객체는
      const item = draft.find(item => item._id === _id);
      item.done = !item.done;
    })

   
    console.log(itemList, newItemList);
    setItemList(newItemList);
  }


  function deleteItem(_id){
    // 상태 변경
    const newItemList = itemList.filter(item => item._id !== _id);
    setItemList(newItemList);

    // console.log(itemList, newItemList);
    //filter를 사용했기 때문에 불변상태를 지킴

  }

  return (
    <div id="todo">
      <Todo itemList={ itemList } addItem={ addItem } toggleDone={ toggleDone } deleteItem={ deleteItem } />
    </div>
  );
}



export default TodoContainer;

 

 


 

 

리액트훅

 

  • 컴포넌트가 렌더링 되는 동안에만 사용하는 특별한 함수
  • 훅을 이용하면 클래스 컴포넌트에서만 사용 가능했던 상태관리와 생명주기 이벤트 기능을 함수형 컴포넌트에서도 사용할 수 있다. 

 

 

 

라이프 사이클

-> 컴포넌트가 생성되고 삭제되기까지의 일련의 이벤트

 

ㄴ 아래 세개는 잘 숙지하고 있자! 

 

 

 

 

useEffect
함수형 컴포넌트에서 는 useEffect 훅을 이용해서 작성하면 된다. 
useEffect(setup[, dependencues]);

 

 

useEffect는 3가지 라이프 사이클이벤트를 등록하기 위한 훅이다. 

 

 

1. 카운터 예제

 

setTimeout으로 1값이 증가하게되면, 상태변수가 변경되었기 떄문에

무.한.렌.더.링 에 빠진다. 

 

하지만,  라이프사이클에 연관하는 (마운트될때만 한번 작동하는) useEffect 를 사용하면,

컴포넌트가 마운트될때만 아래처럼 한번 실행하는 코드를 만들 수 있다. 

  useEffect(() => {
    setTimeout(() => {
      setCount(count + 1);
    }, 1000);
  }, []);

 

  • 첫 번째 인자 - 효과 함수: 컴포넌트가 마운트될 때, 업데이트될 때, 언마운트될 때 실행되는 함수입니다.
  • 두 번째 인자 - 의존성 배열: useEffect 함수가 언제 실행될지 결정하는 배열입니다.

 

 

 

 

 

 

외부에서 데이터를 받아와야 하는 경우에는, useEffect 를 사용할 수 밖에 없다. 

일단 return 에서는 순수하게 리턴하고 (렌더링 후~ )

뭔가 바뀌어야하는 값에 대해서는 useEffect에서 

순수하지 않은 코드를 넣어도 된다!