Do you ever find yourself in React useState hook hell?
Yeah, this good stuff:
import { useState } from 'react'
function EditCalendarEvent() {
const [startDate, setStartDate] = useState()
const [endDate, setEndDate] = useState()
const [title, setTitle] = useState('')
const [description, setDescription] = useState('')
const [location, setLocation] = useState()
const [attendees, setAttendees] = useState([])
return <>
<input value={title} onChange={e => setTitle(e.target.value)} />
{/* ... */}
</>
}
솔직히 더럽긴 하죠 :) 그래서 대안점으로 useReducer를 사용해보라고 하네요,
There is a more powerful alternative to useState
Did you know that there is an alternative state hook that is more powerful and easier to use than you might think?
Using useReducer, we could transform the above code, to just this:
import { useReducer } from 'react'
function EditCalendarEvent() {
const [event, updateEvent] = useReducer((prev, next) => {
return { ...prev, ...next }
}, { title: '', description: '', attendees: [] })
return <>
<input value={event.title}
onChange={e => updateEvent({ title: e.target.value }) } />
{/* ... */}
</>
}
The useReducer hook helps you control transformations from state A to state B.
Now, you could say “I can do that with useState too, see” and point to some code like this:
import { useState } from 'react'
function EditCalendarEvent() {
const [event, setEvent] = useState({
title: '', description: '', attendees: []
})
return <>
<input value={event.title}
onChange={e => setEvent({...event, title: e.target.value }) } />
{/* ... */}
</>
}
아직 reducer가 상태전환에 이점이 있다 정도만 알지, 저도 사용해본적이 없어서 사용해보면서 조금더 파악해봐야할거같요:)
For instance, we may want to always ensure, no matter how and where state is written, that the end date is never before the start date (as that would make no sense), and that the title has a max length of 100 characters:
import { useReducer } from "react";
function EditCalendarEvent() {
const [event, updateEvent] = useReducer(
(prev, next) => {
const newEvent = { ...prev, ...next };
// Ensure that the start date is never after the end date
if (newEvent.startDate > newEvent.endDate) {
newEvent.endDate = newEvent.startDate;
}
// Ensure that the title is never more than 100 chars
if (newEvent.title.length > 100) {
newEvent.title = newEvent.title.substring(0, 100);
}
return newEvent;
},
{ title: "", description: "", attendees: [] }
);
return (
<>
<input
value={event.title}
onChange={(e) => updateEvent({ title: e.target.value })}
/>
{/* ... */}
</>
);
}