TIL_69_Hook
훅에서 clean up의 역할을 하는 것은?
// App.js
import React {useState, useEffect} from 'react';
import './App.css';
function App() {
return (
<div className="container">
<h1>Hello World</h1>
<FuncComp initNumber={2}></FuncComp>
<ClassComp initNumber={2}></ClassComp>
</div>
);
}
let funcStyle = 'color:blue';
let funcId = 0;
function FuncComp(props) {
let numberState = useState(props.initNumber);
let number = numberState[0];
let setNumber = numberState[1];
//let dateState = useState((new Date().toString()));
//let _date = numberState[0];
//let setNumber = numberState[1];
let [_date, setDate] = useState((new Date()).toString());
//side effect
useEffect(function(){
console.log('%cfunc => useEffect (componentDidMount & componentDidUpdate)'+ (++funcId), funcStyle);
document.title = number + ' : ' + _date;
return function(){
console.log('%cfunc => useEffect return (componentDidMount & componentDidUpdate)'+ (++funcId), funcStyle);
}
});
//useEffect (componentDidMount & componentDidUpdate) 2 가 호출
// 그 다음에 랜덤을 클릭하면,
//render3 가 실행 ->
//useEffect return (componentDidMount & componentDidUpdate) 4 가 실행되고
//useEffect (componentDidMount & componentDidUpdate) 5가 실행.
//유즈 이팩트가 실행이 되고나서 다시 똑같은 유즈 이팩트가 실행되기 전에
//뭔가 정리하는 작업이 필요하다면, return 값을 함수로 주면,
//clean up의 역할을 한다.
//유즈 이팩트가 실행이 될 때 초기화를 한 다음에 다시 한번
//그 유즈 이팩트가 실행이 될 때 이전에 실행했던 것을 정리하는 역할->
//return 값에 있는 함수가 호출되는 것.
console.log('%cfunc => render'+ (++funcId), funcStyle);
return (
<div className="container">
<h2>function style component</h2>
<p>Number : {number}</p>
<p>Date : {_date}</p>
<input type="button" value="random" onClick={
function() {
setNumber(Math.random());
}
}></input>
<input type="button" value="date" onClick={
function() {
setDate((new Date()).toString());
}
}></input>
</div>
);
}
클래스 방식에서는 스테이트가 바뀔 때마다 이전의 props 와 이전의 state 값을 전달하여 두 개의 값이 다를 때만 작업을 처리하도록 했었다.
아래의 코드처럼.
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
document.title = `You clicked ${this.state.count} times`;
}
}
스테이트가 바뀔 때마다 인자로 이전의 프롭스 값과 이전의 스테이트 값을 전달 -> 이전의 값과 이후의 변경된 값을 비교해서 그 두 개가 다를 때만 어떠한 작업을 처리한다면 불필요한 처리를 하지 않을 수 있다. -> 즉 성능을 높일 수 있다.
이 과정을 Hook에선 어떻게 쓸 수 있을까?
// App.js
import React {useState, useEffect} from 'react';
import './App.css';
function App() {
return (
<div className="container">
<h1>Hello World</h1>
<FuncComp initNumber={2}></FuncComp>
<ClassComp initNumber={2}></ClassComp>
</div>
);
}
let funcStyle = 'color:blue';
let funcId = 0;
function FuncComp(props) {
let numberState = useState(props.initNumber);
let number = numberState[0];
let setNumber = numberState[1];
//let dateState = useState((new Date().toString()));
//let _date = numberState[0];
//let setNumber = numberState[1];
let [_date, setDate] = useState((new Date()).toString());
//side effect
useEffect(function(){
console.log('%cfunc => useEffect number(componentDidMount & componentDidUpdate)'+ (++funcId), funcStyle);
document.title = number;
//number 라는 state만 참조해서 작업을 하겠다는 뜻.
//즉 number의 값이 바뀌지 않았다면, 위 작업을 할 필요가 없다는 것.
//number의 값이 바꼈을 때만 아래의 return 함수가 호출되도록 해보자.
return function(){
console.log('%cfunc => useEffect number return (componentDidMount & componentDidUpdate)'+ (++funcId), funcStyle);
}, [number]);
//number 배열안에 있는 원자들의 상태가 바꼈을 때만 첫번째 인자인
//콜백함수가 호출이 되도록 약속되어있음.
//변한값에 대해서만 처리를 한다. -> 성능을 향상시킨다.
//return 함수 값은 clean up 할 때 쓰인다.
useEffect(function(){
console.log('%cfunc => useEffect _date (componentDidMount & componentDidUpdate) '+(++funcId), funcStyle);
document.title = _date;
return function(){
console.log('%Cfunc => useEffect _date return (componentDidMount & componentDidUpdate) '+(++funcId), funcStyle);
}
}, [_date]);
console.log('%cfunc => render'+ (++funcId), funcStyle);
return (
<div className="container">
<h2>function style component</h2>
<p>Number : {number}</p>
<p>Date : {_date}</p>
<input type="button" value="random" onClick={
function() {
setNumber(Math.random());
}
}></input>
<input type="button" value="date" onClick={
function() {
setDate((new Date()).toString());
}
}></input>
</div>
);
}
컴퍼넌트 디드 마운트만 하고싶을 때?
useEffect(function(){
console.log('%cfunc => useEffect (componentDidMount) '+(++funcId), funcStyle);
document.title = number;
return function(){
console.log('%cfunc => useEffect return (componentWillUnMount) '+(++funcId), funcStyle);
}
}, []};
위 코드처럼 빈배열을 넣어주면 된다.
빈 배열을 넣어주게 되면 1회만 실행이 되고 그 이후에는 실행이 되지 않는다.
콘솔을 확인해보면 componeneDidMount가 1회만 호출이 되고 더이상 호출이 되지 않은 것을 확인할 수 있다.
나의 이해를 돕기 위해 추가
render 가 되고 useEffect return 함수가 먼저 실행이 되면서 clean up을 한 뒤 useEffect number 가 실행된 것을 확인할 수 있다.
_date 함수는 date를 클릭하지 않았기 때문에 실행되지 않음.
[number] 배열 안에 있는 'number' 가 상태가 변해야만 useEffect 함수가 실행이 되고
return 함수가 있다면 useEffect 가 실행되기 전에 return 함수가 먼저 실행이 되면서 clean up을 한다.
코드를 보자.
주석처리된 return function은 clean up 역할을 하고 그 아래에 [number]가 상태가 바뀌면 실행이 되도록 하는 것.
Author And Source
이 문제에 관하여(TIL_69_Hook), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@poohv7/TIL69Hook저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)