Reactμμ Derived Stateλ₯Ό νμ©νμ¬ μν κ΄λ¦¬νκΈ°
- #React
- #Derived State
λ€μ΄κ°λ©°
μλ νμΈμ. μλμ νλ‘ νΈμλν μ μ κ°λ°μ μ§μλ―Όμ λλ€.
리μ‘νΈμμ μ€μν κ°λ μ€ νλμΈ νμ μν(Derived State)μ λν΄ μμλ³΄λ €κ³ ν©λλ€. νμ μνλ 무μμ΄λ©°, μνλ₯Ό μ λλ‘ κ΄λ¦¬νμ§ μμΌλ©΄ λ°μν μ μλ λ¬Έμ μ κ³Ό ν¨κ³Όμ μΌλ‘ μ¬μ©νλ λ°©λ²μ λν΄ κ³΅μ νλ €κ³ ν©λλ€.
νμ μνλ
νμ μνλ κΈ°λ³Έ μνλ‘λΆν° μ§μ μ μΌλ‘ κ³μ°λ μνλ₯Ό λ§ν©λλ€. μλ₯Ό λ€μ΄ μν λͺ©λ‘μ΄λ νν°λ§λ λ°μ΄ν°μ κ°μ΄ κΈ°μ‘΄ μνμ κΈ°λ°νμ¬ λμ μΌλ‘ λ³νλ μνλ₯Ό μλ―Έν©λλ€.
리μ‘νΈλ‘ κ°λ°νλ€ λ³΄λ©΄, μνλ₯Ό κ΄λ¦¬νλ κ² μΈμλ κ³μ°λ μνλ νμλ μ 보λ₯Ό νμλ‘ ν λκ° μμ΅λλ€. μ΄λ νμ μν κ°λ μ΄ μ€μν μν μ ν©λλ€. νμ μνλ₯Ό ν΅ν΄ μν λ³νμ λν΄ λ¦¬λ λλ§μ λ°©μ§νμ¬ μ ν리μΌμ΄μ μ μ±λ₯μ ν₯μμν€κ³ , 볡μ‘ν λ‘μ§μ κ°κ²°νκ² νννκ³ κ΄λ¦¬ν μ μμ΅λλ€.
μλλ μνμ μ€ν μκ°κ³Ό μ’ λ£ μκ°μ κΈ°λ°μΌλ‘ μνμ μνμ νμ΄λ¨Έλ₯Ό κ³μ°νλ μμμ λλ€.
function formatTime(time) {
const hour = Math.floor((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const min = Math.floor((time % (1000 * 60 * 60)) / (1000 * 60));
const sec = Math.floor((time % (1000 * 60)) / 1000);
const formatHour = String(hour).padStart(2, '0');
const formatMin = String(min).padStart(2, '0');
const formatSec = String(sec).padStart(2, '0');
return `${formatHour}:${formatMin}:${formatSec}`;
}
function GoodsStatusButton({ startTime, endTime }) {
// νμ¬ μκ° μν
const [currentTime, setCurrentTime] = useState(new Date().getTime());
// 1μ΄λ§λ€ νμ¬ μκ°μ μ
λ°μ΄νΈ
useEffect(() => {
const timer = setInterval(() => {
setCurrentTime(new Date().getTime());
}, 1000);
return () => clearInterval(timer);
}, []);
// μν μνλ₯Ό κ³μ°νλ νμ μν
const goodsStatus = useMemo(() => {
if (endTime < currentTime) {
return 'quit';
}
if (startTime > currentTime) {
return 'comingsoon'
}
return 'ready';
}, [currentTime, startTime, endTime]);
return (
<button>
{goodsStatus === 'comingsoon'
? formatTime(startTime - currentTime)
: goodsStatus}
</button>
)
}
μμ μ½λμμ goodsStatus
λ 1μ΄λ§λ€ λ³κ²½λλ currentTime
κ³Ό startTime
, endTime
μνλ€μ κΈ°λ°μΌλ‘ λμ μΌλ‘ κ³μ°λ©λλ€. goodsStatus
κ°μ΄ βcomingsoonβ μ΄λΌλ©΄ κ³μ°λ νμ΄λ¨Έλ₯Ό λ²νΌμ 보μ¬μ€λλ€. μ΄λ κ² νμ μνλ₯Ό νμ©νλ©΄ 볡μ‘ν 쑰건 λ‘μ§μ λ¨μννκ³ , μ ν리μΌμ΄μ
μ μν κ΄λ¦¬λ₯Ό ν¨κ³Όμ μΌλ‘ μνν μ μμ΅λλ€.
μλͺ»λ μ¬μ© μμ
μνλ₯Ό μλͺ» μ¬μ©νμ λ κ²ͺμ μ μλ μΌλ°μ μΈ λ¬Έμ λ€μ μ΄ν΄λ³΄κ² μ΅λλ€.
propsλ₯Ό μνμ 볡μ¬νκΈ°
props
λ₯Ό μνμ 볡μ¬νλ κ²μ λΆνμν λ©λͺ¨λ¦¬ μ¬μ©μ μ΄λν μ μμ΅λλ€. λν, λ¨μΌ μμ€κ° μ‘΄μ¬νμ§ μκ³ λκ°μ μνλ₯Ό κ°μ§κ³ μκΈ° λλ¬Έμ μκΈ°μΉ μμ λμμ΄ λ°μν μ μκ³ μ½λλ 볡μ‘ν΄μ§λλ€.
function GoodsStatusButton({ startTime, endTime }) {
const [startTimeValue, setStartTimeValue] = useState(startTime);
const [endTimeValue, setEndTimeValue] = useState(endTime);
...
}
λΆνμν 리λ λλ§
리μ‘νΈ μ»΄ν¬λνΈμμ νμ μνλ₯Ό κ³μ°ν λ useEffect
λ΄λΆμμ ν΄λΉ μνλ₯Ό μ
λ°μ΄νΈνλ λ‘μ§μ΄ μλ€λ©΄, μν λ³κ²½μ΄ λ λλ§λ€ useEffect
κ° κ³μν΄μ μ¬μ€νλ μ μμ΅λλ€. μ΄λ¬ν μν©μ 무ν 루νλ₯Ό λ°μμν¬ μ μμΌλ©°, μ΄λ₯Ό νΌνκΈ° μν΄ μνμ λ³κ²½ 쑰건μ μ μ μνκ±°λ, μμ‘΄μ± λ°°μ΄μ μ¬λ°λ₯΄κ² μ€μ νλ κ²μ΄ μ€μν©λλ€.
κ°μ νκΈ°
μμ ν¨μ νμ©νκΈ°
μμ ν¨μλ λμΌν μ λ ₯μ λν΄ νμ λμΌν μΆλ ₯μ λ°ννλ ν¨μλ₯Ό μλ―Έν©λλ€. νμ μνμ κ³μ°μ μμ ν¨μλ₯Ό μ¬μ©νλ©΄ μμΈ‘ κ°λ₯νκ³ μμ μ μΈ μν κ΄λ¦¬κ° κ°λ₯ν΄μ§λλ€.
// μμ ν¨μλ₯Ό μ¬μ©ν νμ μν
function computeGoodsStatus(startTime, endTime, currentTime) {
if (endTime < currentTime) {
return 'quit';
}
if (startTime > currentTime) {
return 'comingsoon'
}
return 'ready';
}
useMemo ν μ¬μ©νκΈ°
useMemo
μ μμ‘΄μ± λ°°μ΄μ μ¬μ©νλ©΄ κ³μ° λΉμ©μ΄ λμ νμ μνλ₯Ό ν¨μ¨μ μΌλ‘ κ΄λ¦¬ν μ μμ΅λλ€. μμ‘΄μ± λ°°μ΄μ ν¬ν¨λ κ°μ΄ λ³κ²½λ λλ§ κ³μ°μ΄ μ¬μ€νλ©λλ€.
// useMemoλ₯Ό μ΄μ©ν νμ μν
const goodsStatus = useMemo(() => {
return computeGoodsStatus(startTime, endTime, currentTime);
}, [startTime, endTime, currentTime])
λ§μΉλ©°
νμ μνμ λν μ΄ν΄λ 리μ‘νΈ μ ν리μΌμ΄μ μ μ±λ₯κ³Ό ꡬ쑰μ μμ΄ μ€μν μν μ ν©λλ€. 리μ‘νΈμμ μν κ΄λ¦¬μ λ‘μ§μ΄ 볡μ‘ν΄μ§ λλ§λ€ useStateλ§μ μμ‘΄νλ κ²μ΄ νμ μ΅μ μ λ°©λ²μ μλλλ€. νΉμ μνκ°μ useState μμ΄ μ§μ κ³μ°νκ±°λ νμ μνλ‘ κ΄λ¦¬νλ κ²λ κ³ λ €νλ©΄ μ½λμ 볡μ‘μ±μ μ€μ΄κ³ ν¨μ¨μ μΈ μ½λμ μ¬μ©μ κ²½νμ μ 곡ν μ μμ κ²μ λλ€.
μ΄ κΈμ ν΅ν΄ νμ μνμ λν΄ λμμ΄ λμμΌλ©΄ μ’κ² μ΅λλ€. κ°μ¬ν©λλ€!
λ μ½μ΄λ³Ό μλ£
-
Thinking in react: Find the minimal but complete representation of UI state
The filtered list of products isnβt state because it can be computed by taking the original list of products and filtering it according to the search text and value of the checkbox.
-
You Might Not Need an Effect: Updating state based on props or state
When something can be calculated from the existing props or state, donβt put it in state. Instead, calculate it during rendering
-
Redux Style Guide: Keep State Minimal and Derive Additional Values
Whenever possible, keep the actual data in the Redux store as minimal as possible, and derive additional values from that state as needed.