표현컴포넌트 & 컨테이너 컴포넌트
[표현 컴포넌트 예시 - 상태를 관리하지 않는 컴포넌트] (부모)
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에서
순수하지 않은 코드를 넣어도 된다!
'React Native' 카테고리의 다른 글
React #7 - 리엑트훅(useMemo, useCallback) (0) | 2024.03.12 |
---|---|
React #6 - 리엑트훅(useReducer, useRef) (0) | 2024.03.11 |
React #4 - immer, State, 회원가입 form 실습 (0) | 2024.03.07 |
React #03 - Counter 구현 (0) | 2024.03.05 |
React #02 - 가상 DOM, React 시작하기, vite (0) | 2024.03.04 |