Hook: 여러 컴포넌트 중 function이 class를 사용할 수 있도록 도와주는 기능.
useEffect: useEffect(() ⇒ {함수}, [state or data값])의 형태로, 렌더링 때마다 특정한 작업을 하게 도와준다.
useEffect(() ⇒ {함수})
=⇒ 페이지를 렌더링(mount)할 때마다 함수가 실행된다.
useEffect(() ⇒ {함수}, [state or data값])
=⇒ 첫 렌더링 시에만 함수가 실행된다.
useEffect(() ⇒ {함수}, [state or data값])
=⇒ 해당 state or data값이 변화할 때 함수가 실행된다.
useCallback: 기존의 연산 결과값을 다음 번에 재사용하기 위해 저장해두었다가 함수를 반환하는‘Memoization’의 기능을 구현함.
import {
useCallback,
useEffect,
useState
} from "react";
function Counter() {
console.log('Render Counter')
const [value, setValue] = useState(0);
//useEffect 사용 1. body 클릭시 콘솔에 어떻게 뜨는지 보기
useEffect(() => {
console.log(
'[Function] useEffect []: 컴포넌트가 마운트될 때 한 번만.'
);
const eventHandler = () =>{
console.log('click body');
};
document.body.addEventListener(
'click',
eventHandler
);
return () => {
console.log(
'[Function] useEffect return []: 컴포넌트가 언마운트 될 때.'
);
document.body.removeEventListener(
'click',
eventHandler
);
};
}, []);
// useEffect 사용 2. 컴포넌트 마운트 시 value가 변경 or 새로 useEffect를 수행할 때.
useEffect(() => {
console.log(
'[Function] useEffect [value]: 컴포넌트가 마운트될 때, + value가 변경되면, '
);
const eventHandler = () =>{
console.log('click body');
};
document.body.addEventListener(
'click',
eventHandler
);
return () => {
console.log(
'[Function] useEffect return [value]: 새로 useEffect를 수행하기 전에,'
);
};
},[value]);
return(
<div>
<h1>value:{value}</h1>
<button onClick={increaseValue}>Increase Value</button>
<button onClick={resetValue}>reset Value</button>
</div>
)
}
export default Counter;
import {
useCallback,
useEffect,
useState
} from "react";
function Counter() {
console.log('Render Counter')
const [value, setValue] = useState(0);
// useCallback의 사용법. 이전에 있던 memoization된 값(여기서는 value)을 다음 렌더링에서 재활용하는 방식.
const increaseValue = () => {
setValue(value + 1);
console.log('Render Counter2')
};
const resetValue = useCallback(() => {
setValue(0);
}, []);
return(
<div>
<h1>value:{value}</h1>
<button onClick={increaseValue}>Increase Value</button>
<button onClick={resetValue}>reset Value</button>
</div>
)
}
export default Counter;


import {Component, useEffect, useState} from "react";
//Class Component의 lifecycle. 렌더링을 기반으로 다양한 method들이 실행된다.
class ClassComponent2 extends Component{
state = {
value: 0
};
constructor(props) {
console.log('[Class] Constructor');
super(props);
this.state = {
value: 0
};
}
// 컴포넌트 렌더링 전 실행(return이 false면 렌더링 안함)
shouldComponentUpdate(nextProps, nextState, nextContext) {
console.log('[Class] shouldComponentUpdate');
return true;
}
// 컴포넌트 마운트가 끝나면 실행
componentDidMount() {
console.log('[Class] componentDidMount');
}
// 컴포넌트 업데이트 후 실행
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('[Class] componentDidUpdate');
}
// 컴포넌트 언마운트 직전 실행
componentWillUnmount() {
console.log('[Class] componentWillUnmount');
}
render() {
console.log('[Class] render');
return(
<div>
<h1>ClassComponent</h1>
<h1>value: {this.state.value}</h1>
<button
onClick={()=>{
this.setState((state)=> ({
value: state.value + 1
}));
}}
>
Increase Value</button>
</div>
)
}
}
export default ClassComponent2;
import {useEffect, useState} from "react";
//Functional Component의 구현. useEffect를 사용하여 Mount/Update/UnMount가 모두 처리된다.
function FunctionalComponent() {
console.log('[Function] Beggining'); //Mount 시 1번 로그, Update 시 1번 로그
const [value, setValue] = useState(0);
useEffect(() => { //Mount될 때의 useEffect. //Mount 시 3번 로그, Update 시 생략.
console.log('[Functional] useEffect []');
return() => { //Unmount 시 1번 로그.
console.log(
'[Function] useEffect return []'
);
}
}, []);
useEffect(() => { //value가 update될 때, 위 useEffect는 생략하고 ReRendering된다. //Mount 시 4번 로그, Update 시 4번 로그.
console.log('[Functional] useEffect [value]');
return() => {
console.log(
'[Function] useEffect return [value]'
//Update 시 3번 로그, Unmount 시 2번 로그.
);
}
}, [value]);
console.log('[Function] end'); //Update상황에서 이 로그가 실행된 뒤 화면에 출력된다.
//Mount 시 2번 로그, Update 시 2번 로그
return(
<div>
<h1>FunctionComponent</h1>
<h1>value: {value}</h1>
<button
onClick={()=>{
setValue((state)=>state + 1); //value를 update시키는 trigger.
}}
>Increase Value</button>
</div>
)
}
export default FunctionalComponent;
import {useEffect, useState} from "react";
function Accordion({title, content}){
const [isOpened, setIsOpened] = useState(false);
return(
<div>
<div
style={{
background: '#666',
color: 'white',
fontWeight: 'bold',
padding: 10,
display: 'flex',
justifyContent: 'space-between'
}}
>
<div>{title}</div>
<div
onClick={()=>{
// setIsOpened(!isOpened); //1안. 직접 바꿔주기
setIsOpened((state)=>{
return !state //2안. onClick 내부에서 자체적으로 바꾸기.
});
}}
>{isOpened ? '-' : '+'}</div>
</div>
{isOpened && <div style={{
border: '1px solid #999',
padding: 20
}}
>
{content}
</div>}
</div>
)
}
export default Accordion;