Hook
- ๋ฆฌ์กํธ ๋ฒ์ 16.8์ ์๋ก ๋์ ๋ ๊ธฐ๋ฅ ์ ๋๋ค.
- ํจ์ํ ์ปดํฌ๋ํธ์์๋ ์ํ ๊ด๋ฆฌ๋ฅผ ํ ์ ์๋ useState, ๋ ๋๋ง ์งํ ์ค์ ํ๋ useEffect ๋ฑ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ๊ธฐ์กด์ ํจ์ํ ์ปดํฌ๋ํธ์์ ํ ์ ์์๋ ๋ค์ํ ์์ ์ ํ ์ ์๋๋ก ํฉ๋๋ค.
- Hook์ ํจ์ ์ปดํฌ๋ํธ์์ React state์ ์๋ช ์ฃผ๊ธฐ ๊ธฐ๋ฅ์ ์ฐ๋ํ ์ ์๊ฒ ํด์ฃผ๋ ํจ์ ์ ๋๋ค.
โญ๏ธ useState
- useState()๋ ๋ฆฌ์กํธ์์ ์ํ(state)๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด ์ ๊ณต๋๋ hook ์ ๋๋ค.
- useState()๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์ํ ์ปดํฌ๋ํธ์์๋ ์ํ๋ฅผ ๊ด๋ฆฌํ ์ ์์ผ๋ฉฐ, ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ปดํฌ๋ํธ๊ฐ ์๋์ผ๋ก ๋ค์ ๋ ๋๋ง ๋ฉ๋๋ค.
- useState()๋ ๋ฐฐ์ด ํํ๋ก ๋ณํ๋๋ฉฐ, ์ฒซ ๋ฒ์งธ ์์๋ 'ํ์ฌ ์ํ'์ด๊ณ , ๋ ๋ฒ์งธ ์์๋ '์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์' ์ ๋๋ค. ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์๋ ์๋ฐ์ Setterํจ์์ ๋น์ทํ ์ญํ ์ ํ๋ฉฐ, ์๋ก์ด ์ํ๋ฅผ ์ธ์๋ก ๋ฐ์ ์ปดํฌ๋ํธ๋ฅผ ๋ค์ ๋ ๋๋ง ํฉ๋๋ค.
useState ๊ธฐ๋ณธ
const Usestate = () => {
const [value, setValue] = useState(0); // ์ด๊ธฐ๊ฐ์ 0์ผ๋ก ์ค์
return (
<>
<p>ํ์ฌ ์นด์ดํธ ๊ฐ์ <b>{value}</b></p>
<button onClick={() => setValue(value + 1)}>์ฆ๊ฐ</button>
<button onClick={() => setValue(value - 1)}>๊ฐ์</button>
</>
);
}
export default Usestate;
๐ข '์ฆ๊ฐ' ๋ฒํผ์ ํด๋ฆญํ ๋ ๋ง๋ค(onClick()) value ๊ฐ์ 1 ์ฆ๊ฐ ์ํจ ํ ๋ค์ ๋ ๋๋ง ํด๋ผ.(setValue(value + 1))
๐ข '๊ฐ์' ๋ฒํผ์ ํด๋ฆญํ ๋ ๋ง๋ค(onClick()) value ๊ฐ์ 1 ๊ฐ์ ์ํจ ํ ๋ค์ ๋ ๋๋ง ํด๋ผ.(setValue(value - 1))
์ฐ์ต๋ฌธ์ - ๋ช ํจ ์ถ๋ ฅํ๊ธฐ
โ๏ธ ์ด๋ฆ, ์ง์ฑ , ํ์ฌ๋ช , ํ์ฌ์ฃผ์, ์ด๋ฉ์ผ, ์ ํ๋ฒํธ๋ฅผ ์ ๋ ฅ ๋ฐ์ ๋ช ํจ ํํ๋ก ์ถ๋ ฅํ๊ธฐ
import React, { useState } from 'react';
// 7. ํ๋ฉด์ ์ถ๋ ฅํ ๋ช
ํจ ์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
const NameCard = ({member}) => {
return (
<>
<h3>๋ช
ํจ ์ ๋ณด ์ถ๋ ฅ</h3>
<p>์ด๋ฆ : {member.name}</p>
<p>์ง์ฑ
: {member.position}</p>
<p>ํ์ฌ๋ช
: {member.company}</p>
<p>์ฃผ์ : {member.address}</p>
<p>์ด๋ฉ์ผ : {member.email}</p>
<p>ํธ๋ํฐ : {member.phone}</p>
</>
);
}
const UserState = () => {
const [member, setMember] = useState({ // 1. ๋ช
ํจ ์ ๋ณด ์ ์ฅ์ ์ํ ๊ฐ์ฒด ๋ฆฌํฐ๋ด ์์ฑ
name:"",
position:"",
company:"",
address:"",
email:"",
phone:""
});
const [submit, setSubmit] = useState(false); // 2. ์ ์ถ์ ๋๋ฅด๊ธฐ ์ ๊น์ง๋ ์๋์ค๊ฒ ํ๋ ค๊ณ boolean ํ์
์ผ๋ก ์ค์
// 3. member ๊ฐ์ฒด(์์ ๋น ๊ณต๊ฐ์ ๊ฐ์ฒด)๋ฅผ ํผ์น๊ณ , name์ ์ด๋ฒคํธ๊ฐ ์ผ์ด๋ ๊ฐ์ ๋ฃ๋ ๊ฒ - ๋ค๋ฅธ ํญ๋ชฉ ์ดํ ๋์ผ
// ์ด๋ฒคํธ ํธ๋ค๋ฌ: onChange, onClick ...๋ฅผ ์ด์ฉํด์ ๊ฐ์ ๋ฐ์์ค๊ธฐ
const onChangeName = (e) => setMember({...member, name: e.target.value});
const onChangePosition = (e) => setMember({...member, position: e.target.value});
const onChangeCompany = (e) => setMember({...member, company: e.target.value});
const onChanageAddress = (e) => setMember({...member, address: e.target.value});
const onChangeEmail = (e) => setMember({...member, email: e.target.value});
const onChangePhone = (e) => setMember({...member, phone: e.target.value});
// 4. ๊ฐ์ ์
๋ ฅํ๊ณ ์ ์ถ ๋ฒํผ์ ๋๋ ์ ๋ submit ์ํ๋ฅผ true๋ก ๋ณ๊ฒฝ
const onSubmit = () => {
setSubmit(true);
}
// 5. ์์ ๋ง๋ ๊ฒ๋ค์ ์ ์ ํ ์์น์ ๋ฃ๊ธฐ
return (
<>
<h1>ํ์ ์ ๋ณด</h1>
<input type="text" placeholder='์ด๋ฆ' value={member.name} onChange={onChangeName}/><br />
<input type="text" placeholder='์ง์ฑ
' value={member.position} onChange={onChangePosition}/><br />
<input type="text" placeholder='ํ์ฌ๋ช
' value={member.company} onChange={onChangeCompany}/><br />
<input type="text" placeholder='์ฃผ์' value={member.address} onChange={onChanageAddress}/><br />
<input type="text" placeholder='๋ฉ์ผ' value={member.email} onChange={onChangeEmail}/><br />
<input type="text" placeholder='ํธ๋ํฐ' value={member.phone} onChange={onChangePhone}/>
<button onClick={onSubmit}>์ ์ถ</button>
{/* 6. ์ปดํฌ๋ํธ ๋ฃ์ด์ ์กฐ๊ฑด๋ถ ๋ ๋๋ง */}
{/* member={member} <= member๋ props ์ด๋ฆ์ด๋ผ ์์๋ก ์ค์ ๊ฐ๋ฅ, {member}๋ ๊ฐ์ฒด ๋ฆฌํฐ๋ด ์ด๋ฆ */}
{submit && <NameCard member={member}/>}
</>
);
}
export default UserState;
โญ๏ธ useEffect
- React ํจ์ํ ์ปดํฌ๋ํธ์์ '์๋ช
์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ๋์ฒด'ํ๋ React hook ์
๋๋ค. (ํ์ ์ฌ์ฉ)
๐ข ์๋ช ์ฃผ๊ธฐ? : ํ๋ฉด์ ๋ํ๋ฌ๋ค๊ฐ ์ฌ๋ผ์ง ๋๊น์ง ์ผ๋ จ์ ๊ณผ์ - useEffect๋ 1) ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋ ๋๋ง๋ค ํน์ ๋์์ ์ํํ๊ฑฐ๋, 2) ํน์ ์ํ๊ฐ ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค ๋์์ ์ํํฉ๋๋ค.
- ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฐ๊ณ , ์ด ์ฝ๋ฐฑ ํจ์๋ ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ(ํ๋ฉด์ ๊ทธ๋ ค์ง ๋) ๋๊ฑฐ๋ ์ธ๋ง์ดํธ(ํ๋ฉด์์ ์ฌ๋ผ์ง๋) ๋ ๋, ๊ทธ๋ฆฌ๊ณ ์์กด์ฑ ๋ฐฐ์ด์ ์ ๋ฌ๋ ์ํ๊ฐ ๋ณ๊ฒฝ ๋ ๋๋ง๋ค ์คํ ๋ฉ๋๋ค.
- ๋ ๋ฒ์งธ ์ธ์๋ก ์์กด์ฑ ๋ฐฐ์ด์ด ๋ค์ด๊ฐ๋๋ค. ์์กด์ฑ ๋ฐฐ์ด์ด ๋น ๋ฐฐ์ด์ด๋ฉด useEffect๋ ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ ๋ ๋ ํ๋ฒ๋ง ์คํ ๋ฉ๋๋ค.
useEffect ์์๋ ์๋ฒ์ ๋ณด๋ผ ๋ช ๋ น์ ์์ฑํจ. (axios)
์์กด์ฑ ๋ฐฐ์ด : ๋น๊ต๋ ๋น ๋ฅธ ์๋๋ฅผ ์ํด '์ฃผ์'๋ง ๋น๊ตํ์ฌ ๋ฌ๋ผ์ก์ผ๋ฉด ๋ ๋๋ง ํ๋ค. (๋ถ๋ณ์ฑ์ ๋ฒ์น)
โญ๏ธ useState๋ useEffect๋ฅผ ๊ฐ์ด ๋ฃ์ผ๋ฉด ๋ฌดํ๋ฃจํ์ ๋น ์ง ์ ์์ผ๋ฏ๋ก ์กฐ์ฌ.
import React, { useState, useEffect } from "react";
const UseEffectInfo = () => {
const [name, setName] = useState(""); // ์ด๋ฆ์ด ๋ฐ๋ ๋๋ง๋ค ํ๋ฉด์ ๋ ๋๋ง ํ๊ธฐ ์ํ
const [nickname, setNickname] = useState("");
useEffect(() => {
console.log("๋ ๋๋ง์ด ์๋ฃ ๋์์ต๋๋ค.");
console.log(name, nickname);
}, []);
const onChangeName = e => setName(e.target.value);
const onChangeNickname = e => setNickname(e.target.value);
return (
<>
<div>
<input type="text" value={name} onChange={onChangeName} />
<input type="text" value={nickname} onChange={onChangeNickname} />
</div>
<div>
<p>์ด๋ฆ์ <b>{name}</b></p>
<p>๋๋ค์์ <b>{nickname}</b></p>
</div>
</>
);
}
export default UseEffectInfo;
ํน์ ๊ฐ์ด ์ ๋ฐ์ดํธ ๋ ๋๋ง ์คํํ๊ณ ์ถ์ ๋
- useEffect() ์ ๋๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋๋ ๋ฐฐ์ด ์์ ๊ฒ์ฌํ๊ณ ์ ํ๋ ๊ฐ์ ๋ฃ์ผ๋ฉด ๋ฉ๋๋ค.
- ๋ฐฐ์ด ์์๋ useState๋ฅผ ํตํด ๊ด๋ฆฌํ๊ณ ์๋ ์ํ ๊ฐ์ ๋ฃ์ด๋ ๋๊ณ , props๋ก ์ ๋ฌ๋ฐ์ ๊ฐ์ ๋ฃ์ด๋ ๋ฉ๋๋ค.
import React, { useState, useEffect } from "react";
const UseEffectCnt = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`You clicked ${count} times`);
}, [count]); // count ๊ฐ์ด ๋ฐ๋ ๋๋ง๋ค ์ฝ๋ฐฑํจ์ ์คํ
// useEffect๋ useState์ ๋ณ๊ฐ๋ก ์คํ๋จ. ํ๋ฉด์ด ๊ทธ๋ ค์ง ํ ์์กด์ฑ ๋ฐฐ์ด์ ๊ฐ์ด ๋ฐ๋ ๋ ์คํ.
return (
<>
<p>You Clicked {count} times.</p>
<button onClick={() => setCount(count + 1)}>Click me!</button>
</>
);
}
export default UseEffectCnt;
์๊ฐ ์ ๋ฐ์ดํธ ํ๊ธฐ
- clearInterval() ํจ์๋ JavaScript์์ ์ ๊ณตํ๋ ํจ์๋ก, setInterval() ํจ์๋ก ์์ฑํ ์ธํฐ๋ฒ์ ๋ฉ์ถ๊ฒ ํฉ๋๋ค.
import React, { useState, useEffect } from "react";
const UseEffectClock = () => {
const [time, setTime] = useState(new Date());
useEffect(() => {
const interval = setInterval(() => {
setTime(new Date());
}, 1000);
// ์ธ๋ง์ดํธ ๋๋ฉด interval์ ํด์
return() => clearInterval(interval);
}, []);
return (
<>
<h1>ํ์ฌ ์๊ฐ์ {time.toLocaleTimeString()}</h1>
</>
);
}
export default UseEffectClock;
useReducer
- useReducer๋ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
useState์ ๋ฌ๋ฆฌ, useReducer๋ ๋ณต์กํ ๋ก์ง์ ๊ฐ์ง ์ํ๋ค์ ๊ด๋ฆฌํ๋ ๋ฐ์ ์ ์ฉํฉ๋๋ค. - ์ฒซ ๋ฒ์งธ ์ธ์๋ '์ํ ์
๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์'๋ก์ "reducer"๋ผ๊ณ ๋ถ๋ฆฝ๋๋ค.
๋ ๋ฒ์งธ ์ธ์๋ '์ด๊ธฐ ์ํ' ์ ๋๋ค. ์ด ํจ์๋ ํ์ฌ ์ํ์ ์ก์ (action) ๊ฐ์ฒด๋ฅผ ๋ฐ์์ ์๋ก์ด ์ํ๋ฅผ ๋ฐํ ํฉ๋๋ค. - useReducer๋ฅผ ์ฌ์ฉํ๋ฉด dispatch๋ผ๋ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ฅผ ์ ๋ฐ์ดํธ ํ ์ ์์ต๋๋ค.
- dispatch ํจ์๋ ์ก์ ๊ฐ์ฒด๋ฅผ ๋ฐ๊ณ , ์ด ์ก์ ๊ฐ์ฒด๋ ์ํ๋ฅผ ์ ๋ฐ์ดํธ ํ ๋ ํ์ํ ์ ๋ณด๋ฅผ ํฌํจํ๊ณ ์์ต๋๋ค.
import React, { useReducer } from "react";
// state : ํ์ฌ ์ํ
// dispatch : ์ํ๋ฅผ ์
๋ฐ์ดํธํ๋ ํจ์
// reducer : ๊ฐ๋ฐ์๊ฐ ์ธ๋ถ์ ๋ง๋ค์ด์ผ ํ๋ ํจ์
const reducer = (state, action) => {
// ์ก์
์ ํ์
์ ๋ฐ๋ผ ๋ค๋ฅธ ์์
์ํ
switch(action.type) {
case "INCREMENT" :
return {value: state.value + 1};
case "DECREMENT" :
return {value: state.value -1};
default :
return state;
}
}
const UseReducerCnt = () => {
const [state, dispatch] = useReducer(reducer, {value:0});
return (
<>
<p>ํ์ฌ ์นด์ดํธ ๊ฐ์ <b>{state.value}</b></p>
<button onClick={() => dispatch({type: "INCREMENT"})}>+1</button>
<button onClick={() => dispatch({type: "DECREMENT"})}>-1</button>
</>
);
}
export default UseReducerCnt;
์ ์ฝ๋๋ useState๋ก ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
๋ฐ๋ผ์, ๋ณต์กํ์ง ์์ผ๋ฉด useState์ ๋นํด ํฐ ์ด์ ์ ์์.
Redux์ ๊ฒฐํฉํด์ผ ์ด์ ์ด ์๋๋ฐ ๊ทธ๋ง์ ๋ Context API๋ก ๋์ฒดํด๋ ๋จ
โญ๏ธ useMemo
- ์ปดํฌ๋ํธ์ ์ฑ๋ฅ์ ์ต์ ํํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
- Memo๋ "memorized"๋ฅผ ์๋ฏธํ๋ฉฐ, ์ด์ ์ ๊ณ์ฐํ ๊ฐ์ ์ฌ์ฌ์ฉํ๋ค๋ ์๋ฏธ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- ์ปดํฌ๋ํธ์์ ๋ ๋๋งํ๋ ๋์, ์ปดํฌ๋ํธ์ ์ํ๋ props๊ฐ ๋ณ๊ฒฝ๋๋ฉด ํด๋น ์ปดํฌ๋ํธ์ ํ์ ์ปดํฌ๋ํธ๋ค์ด ๋ค์ ๋ ๋๋ง ๋ฉ๋๋ค.
์ด๋ฌํ ๋ถํ์ํ ๋ ๋๋ง์ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์ผ๊ธฐํ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ด์ ๋ก useMemo๋ฅผ ์ฌ์ฉํ์ฌ ์ต์ ํ ํฉ๋๋ค. - useMemo(๊ณ์ฐํ๋ ํจ์, ์์กด์ฑ ๋ฐฐ์ด)
์ผ๋ฐ์ ์ธ ๊ตฌํ ๋ฐฉ์
- ์ผ๋ฐ์ ์ธ ๊ตฌํ ๋ฐฉ์์ผ๋ก ์์ฑํ ๊ฒฝ์ฐ, Input ๋ด์ฉ์ด ์์ ๋ ๋๋ง๋ค getAverage ํจ์๊ฐ ํธ์ถ๋ฉ๋๋ค.
- input ๋ด์ฉ์ด ๋ฐ๋ ๋๋ง๋ค ...์ฆ ๋ฆฌ๋ ๋๋ง ํ ๋๋ง๋ค ํ๊ท ๊ฐ์ ๊ณ์ฐํ๋ ๊ฒ์ ๋ถํ์ํ ์ผ ์ ๋๋ค.
import { useState } from "react";
const getAverage = numbers => {
console.log("ํ๊ท ๊ฐ ๊ณ์ฐ ์ค");
if(numbers.length === 0) return 0;
// ๋ฐฐ์ด์ ๊ฐ ์์๋ฅผ ์ํํ๋ฉฐ callback ํจ์์ ์คํ ๊ฐ์ ๋์ ํ์ฌ ํ๋์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํ ํฉ๋๋ค.
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => { // ์ปดํฌ๋ํธ ์ด๋ฆ์ ๋๋ฌธ์
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const onChange = e => {
setNumber(e.target.value);
};
const onInsert = e => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
};
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>๋ฑ๋ก</button>
<ul>
{list.map((value, index) => <li key={index}>{value}</li>)}
</ul>
<div>
<b>ํ๊ท ๊ฐ : </b> {getAverage(list)}
</div>
</div>
);
};
export default Average;
useMemo๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์
- useMemo๋ ๋ ๊ฐ์ ์ธ์๋ฅผ ๋ฐ์ต๋๋ค.
์ฒซ ๋ฒ์งธ ์ธ์๋ ์บ์ํ ๊ฐ์ ๊ณ์ฐํ๋ ํจ์์ด๊ณ , ๋ ๋ฒ์งธ ์ธ์๋ ์์กด์ฑ ๋ฐฐ์ด ์ ๋๋ค. - ์์กด์ฑ ๋ฐฐ์ด์ useMemo๊ฐ ์ธ์ ์บ์๋ ๊ฐ์ ๋ค์ ๊ณ์ฐํด์ผ ํ๋์ง ๊ฒฐ์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- ์์กด์ฑ ๋ฐฐ์ด์ ์๋ ๊ฐ์ด ๋ณ๊ฒฝ๋์ง ์์ผ๋ฉด useMemo๋ ์ด์ ์ ์บ์๋ ๊ฐ์ ๋ฐํํ๊ณ , ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ์๋ก์ด ๊ฐ์ ๊ณ์ฐํฉ๋๋ค.
(์ฆ, ์๋ ์์ ์ฝ๋์์ list ๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค getAverage ํจ์๊ฐ ๋ค์ ์คํ ๋ฉ๋๋ค.
list ๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋์ง ์์ ๊ฒฝ์ฐ์๋ ์ด์ ์ ๊ณ์ฐ๋ ๊ฐ์ ์ฌ์ฌ์ฉ ํฉ๋๋ค.)
import React, { useMemo, useState } from "react";
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = e => setNumber(e.target.value);
const onInsert = () => {
// ํ์ฌ ์
๋ ฅ ๋ฐ์ ์ซ์๋ฅผ ๊ธฐ์กด์ ๋ฆฌ์คํธ์ ์ถ๊ฐ(concat์ผ๋ก ์ถ๊ฐ ํ์ผ๋ฏ๋ก ์๋ก์ด ๋ฐฐ์ด์ด ์์ฑ๋จ.
// ๐ ๋ถ๋ณ์ฑ์ ์์น
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
}
const getAverage = numbers => {
console.log("ํ๊ท ๊ฐ ๊ณ์ฐ์ค..");
if(numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a+b, 0);
return sum / numbers.length;
}
const avg = useMemo(() => getAverage(list),[list]);
return (
<>
<input type="text" value={number} onChange={onChange} />
<button onClick={onInsert}>๋ฑ๋ก</button>
<ul>
{list.map((value, index) => <li key={index}>{value}</li>)}
</ul>
<div>
<b>ํ๊ท ๊ฐ : </b> {avg}
</div>
</>
);
}
export default Average;
useCallback
- useCallback์ useMemo์ ์๋นํ ๋น์ทํ ํจ์ ์ ๋๋ค.
- ์ฃผ๋ก ๋ ๋๋ง ์ฑ๋ฅ์ ์ต์ ํํด์ผ ํ๋ ์ํฉ์์ ์ฌ์ฉํ๋ฉฐ, useCallback์ ์ฌ์ฉํ๋ฉด ๋ง๋ค์ด๋จ๋ ํจ์๋ฅผ ์ฌ์ฌ์ฉ ํ ์ ์์ต๋๋ค.
import { useState, useMemo, useCallback } from "react";
const getAverage = numbers => {
console.log("ํ๊ท ๊ฐ ๊ณ์ฐ ์ค");
if(numbers.length === 0) return 0;
// ๋ฐฐ์ด์ ๊ฐ ์์๋ฅผ ์ํํ๋ฉฐ callback ํจ์์ ์คํ ๊ฐ์ ๋์ ํ์ฌ ํ๋์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํ ํฉ๋๋ค.
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => { // ์ปดํฌ๋ํธ ์ด๋ฆ์ ๋๋ฌธ์
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []); // ๋น ๋ฐฐ์ด์ ๋ฃ์ผ๋ฉด ์ฒ์ ๋ ๋๋ง๋ ๋๋ง ํจ์ ํธ์ถ
const onInsert = useCallback(() => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
}, [number, list]);
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>๋ฑ๋ก</button>
<ul>
{list.map((value, index) => <li key={index}>{value}</li>)}
</ul>
<div>
<b>ํ๊ท ๊ฐ : </b> {avg}
</div>
</div>
);
};
export default Average;
useRef
- ํจ์ ์ปดํฌ๋ํธ์์ ref๋ฅผ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ํด์ค๋๋ค.
- useRef๋ฅผ ์ฌ์ฉํ์ฌ ref๋ฅผ ์ค์ ํ๋ฉด useRef๋ฅผ ํตํด ๋ง๋ ๊ฐ์ฒด ์์ current๋ฅผ ๊ฐ๋ฆฌํต๋๋ค.
import { useState, useMemo, useCallback, useRef } from "react";
const getAverage = numbers => {
console.log("ํ๊ท ๊ฐ ๊ณ์ฐ ์ค" + numbers);
if(numbers.length === 0) return 0;
// ๋ฐฐ์ด์ ๊ฐ ์์๋ฅผ ์ํํ๋ฉฐ callback ํจ์์ ์คํ ๊ฐ์ ๋์ ํ์ฌ ํ๋์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํ ํฉ๋๋ค.
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => { // ์ปดํฌ๋ํธ ์ด๋ฆ์ ๋๋ฌธ์
const [list, setList] = useState([]);
const [number, setNumber] = useState(0);
const inputEl = useRef(null);
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []); // ๋น ๋ฐฐ์ด์ ๋ฃ์ผ๋ฉด ์ฒ์ ๋ ๋๋ง๋ ๋๋ง ํจ์ ํธ์ถ
const onInsert = useCallback(() => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber(0);
inputEl.current.focus();
}, [number, list]);
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} ref={inputEl} />
<button onClick={onInsert}>๋ฑ๋ก</button>
<ul>
{list.map((value, index) => <li key={index}>{value}</li>)}
</ul>
<div>
<b>ํ๊ท ๊ฐ : </b> {avg}
</div>
</div>
);
};
export default Average;
'๐จ Frontend > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐ฎ React - 10. ๋ฆฌ์กํธ ๋ผ์ฐํฐ๋ก SPA (2) | 2023.04.19 |
---|---|
๐ฎ React - 9. ์ปดํฌ๋ํธ ์คํ์ผ๋ง (0) | 2023.04.18 |
๐ฎ React - 7. ์ปดํฌ๋ํธ ๋ฐ๋ณต (Array, Map) (0) | 2023.04.13 |
๐ฎ React - 6. Ref์ DOM (0) | 2023.04.13 |
๐ฎ React - 5. ์ด๋ฒคํธ ํธ๋ค๋ง (0) | 2023.04.12 |