반응형
타입설정과 useState
list들의 타입을 정해주고, map 돌릴 list state와 새로 추가할 newTodo state를 만들어준다.
type Lists = {
id:number,
title:string,
checked:boolean,
}
...
const [list, setList] = useState<Lists[]>([]);
const [newTodo, setNewTodo] = useState({
id: new Date().getTime(),
title: "",
checked: false,
});
Mark up
볼만하게 커스터마이징을 해준다.
<section>
<div className="flex-center">
<div className="base-input-wrap minmax300">
<input type="text" name="title" value={newTodo.title} onChange={onChangeInput} className="base-input" placeholder="list name" />
</div>
<button className="base-btn ml10" onClick={addList} disabled={!newTodo.title}>
추가
</button>
</div>
<ul className="font16 mt20">
{list.map((item, index) => {
return (
<li key={index} className="flex-center-between">
<div>
<input type="checkbox" className="mr10" value={item.id} checked={item.checked} onChange={(e) => onCheckboxClick(index)} />
<span className={item.checked ? "text-line text-primary4" :''}>{item.title}</span>
</div>
<button className="only-text-btn text-red" onClick={() => removeList(index)}>remove</button>
</li>
);
})}
</ul>
</section>
기능구현
localStorage에 setItem 할때는 문자열로 넣어주고, getItem 할때는 파싱해서 꺼낸다.
새로고침해도 localStorage에 저장된 리스트가 있다면 state에 set해주기 때문에 날아가지 않는다.
id 값을 비교하여 필터링해도 된다.
const onChangeInput = (e: React.ChangeEvent<HTMLInputElement>) => {
const newTodoTemp = { ...newTodo, [e.target.name]: e.target.value };
setNewTodo(newTodoTemp); // 인풋 value가 바뀔때마다 새로운 todo를 set해준다
};
const addList = () => {
if (newTodo.title) { // 새로 추가될 todo title 값이 있으면
const newList = list.concat(newTodo); //기존 list에 new Todo를 추가하고
setList(newList); // set해준다
localStorage.setItem('todos', JSON.stringify(newList)); //로컬스토리지에도 set한다.
}
setNewTodo({ ...newTodo, title: "" }); // input 초기화
};
const removeList = (index: any) => {
const removedList = list.filter((_, i) => i !== index); //클릭한 요소를 제외한 새 배열을 만들어
setList(removedList); // list를 교체한다.
localStorage.setItem('todos', JSON.stringify(removedList));
};
const onCheckboxClick = useCallback((index: number) => {
const newList = list.map((item, i) => i === index ? {...item, checked: !item.checked} : item);
setList(newList);
localStorage.setItem('todos', JSON.stringify(newList));
}, [list]);
useEffect(()=>{
const localList = localStorage.getItem('todos');
if(localList) setList(JSON.parse(localList)); //최초 렌더링 시 로컬스토리지에 저장된 값이 있으면 리스트에 셋한다.
},[])
반응형
'[IT] 프로덕트 개발 > React - 리액트' 카테고리의 다른 글
react-query 리액트쿼리를 알아보자 (useQuery, staleTime과 cacheTime) (0) | 2022.10.15 |
---|---|
React Router v6 설정하기 / match param, protectedRoute (0) | 2022.10.12 |
[React Hook] useEffect를 알아보자 (1) | 2022.09.10 |
[React] 리스트 추가하고, 클릭시 제거하기 / map, filter (2) | 2022.09.09 |
[React] useState를 사용하여 인풋 만들기 (3) | 2022.09.07 |