Javascript
에서는 HTML
태그에 사용자가 직접 커스텀 속성을 할당할 수 있다.
커스텀 속성을 작성할 때는 원하는 속성명 앞에 data-
를 추가해야 하고, Javascript
에서 dataset
을 통해 한번에 관리할 수 있다.
function practice() {
const [name, setName] = useState("naver");
const onClickName = (e: React.MouseEvent<HTMLDivElement>) => {
const {
currentTarget: {
dataset: { name },
},
} = e;
console.log(name); // "naver" or "kakao"
setName(name!);
};
return (
<div onClick={onClickName} data-name="naver">
naver
</div>
<div onClick={onClickName} data-name="kakao">
kakao
</div>
);
}
위와 같이 div
태그에 data-속성명
으로 커스텀 속성을 지정한다. 그리고 div
태그를 클릭했을 때 해당 속성을 관리하기 위해서 event
객체를 받아온다. event
객체의 curretTarget
에 dataset
이 존재하고, 앞서 지정한 속성명으로 원하는 값에 접근할 수 있다.
주의
처음 dataset
속성을 활용한 것은 React
환경이 아닌 순수 Javascript
환경이었다. 이 때는 event
객체의 target
에 dataset
이 들어있었다.
하지만 React
환경에서는 target
이 아니라 currentTarget
이므로, 이에 주의하도록 하자.
페이지를 새로고침 하는 경우 저장소에 저장된 상태를 유지하기 위해 사용되는 리액트 라이브러리
yarn add recoil-persist
--
npm install recoil-persist
import { atom } from "recoil";
import { recoilPersist } from 'recoil-persist'
const { persistAtom } = recoilPersist({
key: 'recoil-persist'
})
export const myState = atom({
key: "state",
default: [],
effects_UNSTABLE: [persistAtom],
});
위와 같이 atom()
함수의 인자에 effects_UNSTABLE
을 추가하고, value
값으로는 앞서 생성한 persistAtom
객체를 배열 형태로 넣어준다.
이 때, persistAtom
객체의 key
값은 로컬 저장소에 데이터가 저장될 때의 key
에 해당된다.
앞서 알아본 recoil-persist
를 활용하여 좋아요 기능을 구현했다. DB
를 따로 사용하지 않는 개인 프로젝트라서 Local Storage
를 활용했고, recoil-persist
를 통해 간결한 코드를 작성할 수 있었다.
function Movie() {
// ...
const onClickHeart = (e: React.MouseEvent<HTMLDivElement>, movie: IMovie) =>
{
e.stopPropagation();
setFavs((favs: IMovie[]) => {
const prevFavs = [...favs];
const favIndex = prevFavs.findIndex((fav) => fav.id === movie.id);
let resultFavs;
if (favIndex === -1) {
resultFavs = [...prevFavs, movie];
} else {
prevFavs.splice(favIndex, 1);
resultFavs = prevFavs;
}
return resultFavs;
});
};
return (
// ...
<Hearts
onClick={(e) => onClickHeart(e, movie)}
clickedhearts={
favs.find((fav) => fav.id === movie.id) && true + ""
}
>
{favs.find((fav) => fav.id === movie.id) ? (
<HeartFilled />
) : (
<HeartOutlined />
)}
</Hearts>
//...
);
}
위는 프로젝트의 코드 일부를 가져온 것이다.
Hearts
태그를 클릭하면 event
객체와 영화 정보가 담긴 객체를 인자로 받아온다. 받아온 영화 정보를 findIndex()
메서드를 활용하여 기존에 favs
에 저장되어 있던 값들과 비교한다. 같은 것이 없다면 이를 favs
에 추가하여 반환하고, 있다면 splice()
메서드로 해당 영화를 제거한 뒤 반환한다.
그리고 favs
에 현재 찾고 있는 영화가 존재한다면 <HeartFilled />
를 랜더링하고, 그렇지 않다면 <HeartOutlined />
를 랜더링한다.