제작 기한 : 2025. 02. 24 ~ 2025. 03. 08(last updating)
사이트 링크 / 깃허브 링크
오프라인 거래를 할 때 상품을 관리할 수 있는 사이트입니다.
사용 스택
- NextJS(v14)
- material-tailwind
- recoil
- vercel
파일 구조
/src
├── /actions # 데이터 관리 함수를 관리하는 폴더
├── /api # 'use server'를 사용하기 위한 폴더
├── /app
├── /components
├── /config # 'use client'를 layout에 적용시키기 위한 폴더
├── /hooks
├── /model # type 정리 폴더
└── /recoil
// 오류가 난 코드
const AddItem = () => {
const [name, setName] = useState('');
const [cost, setCost] = useState<number>();
...
const onClickHandler = () => {
...
setName('');
setCost(undefined);
};
return (
<BottonBox>
<Input
label='상품명'
type='text'
value={name}
onChange={(e) => {
setName(e.target.value);
setIsError(false);
}}
className='bg-white'
error={isError ? true : false}
/>
<Input
label='가격'
type='number'
value={cost}
onChange={(e) => setCost(Number(e.target.value))}
className='bg-white'
/>
</BottonBox>
);
};
export default AddItem;
onClickHandler
함수가 정상적으로 실행된 후, setState를 통해 기본값으로 초기화시키는 코드를 작성. setName('')은 정상적으로 작동하였으나, setCost(undefined)는 작동하지 않고 기존 value가 그대로 남아있는 문제 발생.input
은 value가 null이나 undefined일 경우 A component is changing a controlled input to be uncontrolled.
경고 메시지를 발생시키는 것을 확인input
초기화 방식과 비교const AddItem = () => {
const [name, setName] = useState('');
const [cost, setCost] = useState<number | ''>('');
...
const onClickHandler = () => {
...
setName('');
setCost('');
};
return (
<BottonBox>
<Input
label='상품명'
type='text'
value={name}
onChange={(e) => {
setName(e.target.value);
setIsError(false);
}}
className='bg-white'
error={isError ? true : false}
/>
<Input
label='가격'
type='number'
value={cost}
onChange={(e) => setCost(Number(e.target.value))}
className='bg-white'
/>
</BottonBox>
);
};
export default AddItem;
undefined
나 null
대신 ''(빈 문자열)
로 설정하여 초기화localStorage
에 저장localStroage
사용localStorage.clear()
'를 통해 24시간 제한마저 없어질 수 있음 = 24시간 내에 재전송 가능localStorage