라이프사이클 React Hook useEffect useRef Promise.all
컴포넌트 생명주기(Life Cycle)
React 컴포넌트는 생명 주기가 있다. 생명주기 메서드는 컴포넌트가 브라우저상에 나타나고, 업데이트되고, 사라지게 될 때 호출되는 메서드들 입니다. 추가적으로 컴포넌트에서 에러가 났을 때 호출되는 메서드도 있습니다.
생명주기 메서드는 클래스형 컴포넌트에서만 활용하고, 함수형 컴포넌트는 Hook을 사용한다.
-
그리기
➤render
-
그리고 난 뒤
➤componentDidMount
-
그리고 난 뒤 변경됐을 때
➤componentDidUpdate
-
그리고 난 뒤 사라질 때
➤componentWillUnmount
참고
클래스형 컴포넌트 생명주기
import { Component, createRef } from "react";
import Router from "next/router";
interface IState {
count: number;
}
export default class ClassComponentLifecyclePage extends Component {
inputRef = createRef<HTMLInputElement>();
state = {
count: 0,
};
// 컴포넌트가 그려지고 난 이후에
componentDidMount = () => {
console.log("컴포넌트 마운트 완료");
this.inputRef.current.focus();
};
componentDidUpdate = () => {
console.log("컴포넌트 수정 완료");
};
// 컴포넌트 사라질 때 페이지 이동하면 잘가요~~ 왜 필요? 채팅 방에서 나가는 경우 알림
componentWillUnmount = () => {
console.log("잘가요~~");
};
onClickCount = () => {
this.setState((prev: IState) => ({
count: prev.count + 1, // prev 가 가지고있는 count
}));
};
onClickMove = () => {
Router.push("/");
};
render() {
return (
<>
현재카운트: {this.state.count}
<button onClick={this.onClickCount}>카운트 증가!!</button>
<button onClick={this.onClickMove}>페이지 이동하기</button>
<input type="text" ref={this.inputRef} />
</>
);
}
}
함수형 컴포넌트 생명주기
import { useEffect, useState, useRef } from "react";
import { useRouter } from "next/router";
export default function FunctionalComponentLifecycle() {
const router = useRouter();
const [count, setCount] = useState(0);
// 위에를 이렇게 쓸 수도 있음
// const [state, setState] = useState({
// count: 0
// })
const inputRef = useRef<HTMLInputElement>();
// componentDidMount 와 동일
useEffect(() => {
console.log("컴포넌트 마운트 완료!!");
inputRef.current.focus();
// componetWillUnmount 와 동일(사라지는 작업을 할 때는 이부분에서)
return () => {
console.log("잘가요~~");
};
}, []); // [ ] 의존성배열
// componentDidUpdate 와 동일 ( 100% 일치하지는 않음. 처음에 한번 무조건 실행(console)되는 성격때문에)
useEffect(() => {
console.log("컴포넌트 수정 완료!!");
});
// setState와 useEffect
// useEffect(() => {
// setCount((prev) => prev + 1)
// }, [])
// setState와 useEffect의 dependency-array
// useEffect(() => {
// setCount((prev) => prev + 1);
// }, [count]);
function onClickCount() {
setCount((prev) => prev + 1);
}
function onClickMove() {
router.push("/"); // 아무페이지나 이동
}
return (
<>
현재카운트: {count}
<button onClick={onClickCount}>카운트 증가!!</button>
<button onClick={onClickMove}>페이지 이동</button>
<input type="text" ref={inputRef} />
</>
);
}
React hooks
- useEffect
Hooks에서는 useEffect를 통해 Lifecycle을 관리한다.
useEffect는 클래스 생명주기 메소드에서 componentDidMount
와 componentDidUpdate
, componentWillUnmont
세 가지 역할을 한다.
useEffect
는 컴포넌트가 그려진 이후에 실행되는 함수이다. 콜백 함수를 가지며, 의존성 배열(Dependency)이 있을 수도 있고 없을 수도 있다. 무조건 렌더링 후 한번 실행된다.
1. 의존성 배열(Dependency)이 없는 경우
useEffect(() => {
console.log("컴포넌트 수정 완료!!");
});
어떤 값이 변화하면 그것을 인지하고 실행된다. 그래서 불필요한 실행이 많이 발생한다.
2. 의존성 배열(Dependency)이 있는 경우
// componentDidMount 와 동일
useEffect(() => {
console.log("컴포넌트 마운트 완료!!");
inputRef.current.focus();
// componetWillUnmount 와 동일(사라지는 작업을 할 때는 이부분에서)
return () => {
console.log("잘가요~~");
};
}, []); // [ ] 의존성배열
빈 의존성 배열이 있으면, 렌더링 후 딱 단 한 번만 실행되고 다시는 실행되지 않는다.
3. 의존성 배열(Dependency) 안에 특정 변수 지정하는 경우
useEffect(() => {
setCount((prev) => prev + 1);
}, [count]);
렌더링 후 한번 실행되고, 의존성 배열 안의 변수의 값이 변할 때 만 실행된다.
- useRef
특정 태그를 조작하기 위해 선택할 때 사용하는 도구이다.
JavaScript 를 사용 할 때에는, 특정 DOM
을 선택해야 하는 상황에 getElementById
, querySelector
같은 DOM Selector 함수를 사용해서 DOM 을 선택한다. react
에서는 ref
를 사용해서 DOM을 선택한다.
useRef
는 current
속성을 가지는 객체를 반환하는데, 인자로 넘어온 초기값을 current
속성에 할당한다. current
속성은 값을 변경해도 상태를 변경할 때처럼 렌더링되지 않는다.
예) input 태그해서 커서 깜빡깜박, 특정 엘리먼트의 크기/색상 변경, 스크로라 위치 가져오기 등..
const inputRef = useRef<HTMLInputElement>();
useEffect(() => {
console.log("컴포넌트 마운트 완료!!");
inputRef.current.focus();
return () => {
console.log("잘가요~~");
};
}, []);
// useRef로 이미지 등록 구현하기
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
inputRef.current?.focus();
}, []);
return <input type="password" ref={inputRef} />;
import { useRef } from 'react';
export default function Web() {
const inputEl = useRef();
const readImage = (input) => {
// 인풋 태그에 파일이 있는 경우
if (input.target.files && input.target.files[0]) {
// FileReader 인스턴스 생성
const reader = new FileReader();
// reader가 이미지 읽도록 하기
reader.readAsDataURL(input.target.files[0]);
// 이미지가 로드가 된 경우
reader.onload = (e) => {
const previewImage =document.getElementById('image');
previewImage.src = e.target.result;
}
}
};
const handleFileBtn = () => {
inputEl.current.click();
};
return (
<>
<div>
<img onClick={handleFileBtn} style={{ width: '500px' }} id="image" />
<input
hidden={true}
ref={inputEl}
id="fileTag"
type="file"
onChange={readImage}
></input>
<button onClick={handleFileBtn}>이미지 등록 버튼</button>
</div>
</>
);
}
Promise.all
동기 요청을 한 번에 보내는 역할을 한다.
Promise
비동기 처리할 때 데이터를 주긴 줄게, 약속만 하는거. 아직 안줌. Promise를 동시에 받는 방법이 있음 ➤ Promise.all([배열])
//시간 재는거
const start = performance.now();
//이미지를 5개를 넣는 다고 가정. 업로드를 5번 해줘야함. async await 이라 순서대로 기다려야함. 총 5번 뮤테이션 너무 오래걸림. 동시에 올리는 방법을 해야함.=> Promise.all
const result1 = await uploadFile({variables: {file: myFile}}),
const result2 = await uploadFile({variables: {file: myFile}}),
const result3 = await uploadFile({variables: {file: myFile}}),
const result4 = await uploadFile({variables: {file: myFile}}),
const result5 = await uploadFile({variables: {file: myFile}});
const end = performance.now();
// console.log(end - start);
async function onClickSubmit() {
const start = performance.now();
Promise.all([
uploadFile({ variables: { file: myFile } }),
uploadFile({ variables: { file: myFile } }),
uploadFile({ variables: { file: myFile } }),
uploadFile({ variables: { file: myFile } }),
uploadFile({ variables: { file: myFile } }),
]);
// 5개 동시에 보내고 동시에 받고. => 5개 동시에 보내고 5개 다 받을 때까지 await
Author And Source
이 문제에 관하여(라이프사이클 React Hook useEffect useRef Promise.all), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@h1225hs/react-hook저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)