생명 주기 (라이프 사이클)
페이지 처음 열렸을 때 ~ 페이지가 닫혔을 때 까지
이 사이에 일어나는 이벤트나 상태 값 변경등을 관리
* 옛날에는 클래스형 사용했다
class 클래스명 extends Components {
...
};
Class형의 문제점:
Class는 다양한 기능을 사용할 수 있지만 기계와 사용자를 혼돈시킨다.
숙련된 React 개발자 조차도 Class의 완벽한 이해를 하는 것은 힘든 일
===> 함수형으로 리엑트를 만들어보자 해서 나온게 function형 리액트의 등장
===> class 형에서 관리하던 생명주기를 function에서 관리를 해줘야하는데 그를 위해서 등장한게 Hooks함수
Hooks 함수(함수형에서만 사용 가능)
(이해할때 그냥 대충 class형이 있었는데 너무 어려워서 함수형을 쓰게 되었다,
생명주기 function에서 관리 안될거같아서 나온게 hook이다)
클래스 형에서도 생명주기는 관리 가능 했다 하지만 클래스 형이 리액트 개발자가 사용하기에는 너무 어렵고 혼동을
많이 시키니까 그래서 함수형을 만들었는데 클래스에 있던 생명주기를 함수형에도 사용할수있게 하기위해 훅함수가 나왔다
1. useState
- Hooks 의 상태 관리 함수
- 컴포넌트에서 바뀌는 값을 관리
- 값이 바뀐 것을 감지하여 랜더링
const [변수명, 변수 값을 바꿔줄 함수명 ] = useState(변수의 기본값)
2. useRef
- js에서 getElementById, querySelector 같은 DOM SELECTOR 함수처럼
- React에서 DOM에 접근하게 되는 일이 생긴다면 접근하게 해주는 Hooks 함수
3. useMemo
- 연산된 값(결과)를 반환하여 재사용할 수 있게 해주는 Hooks 함수
4. useCallback
- 특정 함수를 새로 만들지 않고 재사용할 수 있게 해주는 Hooks 함수
** 렌더링 될 때 변경되지 않는 내용 (onChangeColor)를 다시 생성하지않고
그대로 두고 다시 렌더링 하기때문에 시간이 절약된다
- useMemo와 Callbcack을 사용해서 어떻게 최적화를 할 수 있나??
메모이제이션
: 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술이다. 동적 계획법의 핵심이 되는 기술이다.
- 만약 어떠한 연산이나 함수가 복잡해서 결과가 오래걸린다 (예) 30초)
- 리엑트는 상태가 바뀌면 랜더링한다, 하지만 랜더링 될 때 값이 바뀌지 않는 부분이라면 한번 더
실행해야할 필요가 있을까? -> 시간낭비
- 값이 안바뀌는 연산이나 함수를 랜더링이 되더라도 재생성하지 않도록 값이나 함수를 재사용
즉, 랜더링 시 필요 없는 연산의 시간을 줄여주기 위해 사용
HOOK 함수 사용 예제

import React, {useState} from "react";
import AddState from "./addState";
const State = () => {
const [state, setState] = useState ([
{
id:1,
name:"김사과"
},
{
id:2,
name:"반하나"
},
{
id:3,
name:"이멜론"
}
])
const onClickEvent = (idvalue, namevalue) => {
setState([...state, {id: idvalue, name: namevalue}])
}
const onRemove = (e) =>{
console.log(typeof e.target.value)
// 매우 중요, 작동하지 않을 시 type 을 찍어보는 것
const removeState = state.filter((item) => item.id !== parseInt(e.target.value))
setState(removeState);
// map = 반복 , filter = 거르다
// 선택한 item.id의 값과 다른것만 removeState 에 담아줘
}
return (
<>
{state.map((item) => (
<div key={item.id}>
{item.id}. {item.name}
<button value={item.id} onClick={onRemove}>삭제</button>
</div>
))}
<AddState onClickEvent={onClickEvent} stateId={state.length > 0 && state[state.length-1].id}/>
</>
)
}
export default State;
State.js (메인)
import React, {useState, useRef } from "react";
const AddState = ( {onClickEvent, stateId} ) => {
const [name, setName] = useState("");
const userName = useRef();
const onChangeEvent = (e) => {
setName(e.target.value)
console.log(name);
}
// onchange 함수를 사용해서 name값을 바꿔주기
const onAddState = () => {
onClickEvent( stateId+1, name);
onReset();
}
const onReset = () => {
setName("");
userName.current.focus();
}
return(
<>
<input
type="text"
placeholder="이름을 입력하세요"
value={name}
onChange={onChangeEvent}
ref={userName}
/>
<button onClick={onAddState}>추가</button>
<button onClick={onReset}>초기화</button>
</>
)
}
export default AddState;
addState.js
* ...state로 복사해서 사용하는 이유
state의 불변성
const obj = {}
const obj2 = {} // obj === obj2 (false)
const obj3 = obj //obj와 같은 참조 값을 가진다 (데이터를 바꾸면 원본도 바뀜)
따라서 obj가 가지고 있는 객체 값이 변경되면 obj도 같은 객체를 가지기 때문에 값이 변경된다.
즉, 데이터의 원본이 훼손된다. 이러한 훼손은 예상치 못한 오류와 버그를 발생한다. (원본이 훼손되면 그 전값과 비 교할게 없어져서 )
원본데이터 훼손되는걸 막기 위해 나온 방법
<얕은 복사의 에러를 막기 위해 깊은 복사 실현하는 방법>
1. sereact operator (...)
2. immer.js
(...) => 코드가 길어지고 불편하기 때문에 한번에 해결해줄게 하고 반들어진 라이브러리
draft.state = 변경된 스테이트 값 (draft가 알아서 지켜줌)
* 삭제 구현할때 오류나는 이유
typeof찍어보면 string으로 되어있어서 그니까 형변환 해주기
**중요 : 뭔가 오류가 났을 때 typeof 찍어봐서 뭐가 문젠지 확인해보기
const onRemove = (e) =>{
console.log(typeof e.target.value)+
// 매우 중요, 작동하지 않을 시 type 을 찍어보는 것
const removeState = state.filter((item) => item.id !== parseInt(e.target.value))
setState(removeState);
// map = 반복 , filter = 거르다
// 선택한 item.id의 값과 다른것만 removeState 에 담아줘
* 삭제하니까 밑에 추가하는 부분까지 없어지는거
<AddState onClickEvent={onClickEvent} stateId={state.length > 0 && state[state.length-1].id}/>
전달해줄 state.id가 없어져서 오류가 나는거니까 state가 있을때만 실행하도록
'Front-end > React' 카테고리의 다른 글
| [React 02] Styled-components, 삼항연산자, 비구조화 할당 (0) | 2022.05.02 |
|---|---|
| [React 01] React 란? (0) | 2022.05.01 |