export const getData = selector({
key: 'getData',
get: async ({ get }) => {
const value1 = get(oneValueState);
const value2 = get(twoValueState);
const value3 = get(threeValueState);
let paramsObj = {
one: value1,
two: value2,
three: value3,
};
const response = await axiosInstance.get(`/products`, {
params: paramsObj,
});
return response.data;
},
});
위 코드는 내가 oneValueState, twoValueState, threeValueState라는 Atom을 설정해두고, onChange이벤트가 일어나 이들의 Atom state값이 바뀌게 되면 이 state의 value를 params로 하여 GET요청을 보내는 부분이다.
그런데, value1의 devfault값이 1이라고 하면, 1에서 2로 값이 update되는 순간 GET요청을 보내지만, 다시 2에서 1로 값이 바뀌게 되면 GET요청을 보내지 않는 것을 확인할 수 있었다. 이에 대해서 검색을 해보던 중 Recoil의selector의 option들 중에 cache에 관련된 option이 존재한다는 것을 알게 되었다.
(출처: Recoil 공식문서)
selector에서 사용할 수 있는 새로운 cachePolicy_UNSTABLE 속성은 selector 내부의 캐시 동작 방식을 직접 설정할 수 있게 해준다. 이 속성을 통해 많은 양의 selector를 가지고 있는 애플리케이션이나 다량의 의존성을 가지고 있는 selector 환경에서 메모리 사용을 줄일 수 있는 기능을 제공하는데, 사용 가능한 option은 3가지가 있다.
따라서, 내가 겪었던 문제는 cachePolicy_UNSTABLE option의 기본값인 'keep-all'이 적용되어 있어 생긴 문제이고, 이를 'most-recent'로 바꾸니 해결할 수 있었다. 그렇다면, 이를 어떻게 활용할 수 있을까.
const getClockState = selector({
key: "getClockState",
get: ({ get }) => {
const hour = get(hourState);
const minute = get(minuteState);
const second = get(secondState);
return `${hour}:${minute}:${second}`;
},
cachePolicy_UNSTABLE: {
eviction: "most-recent",
},
});
위와 같이 1초마다 랜더가 되는 selector가 있다고 하면 매초마다 값을 메모리에 저장하게 되는데, 이는 시간이 지남에 따라 내부 cache가 무제한으로 증가하여 메모리에 영향을 줄 수 있다.
따라서, selector의 cache 옵션인 'most-recent'를 사용하면 내부 캐시는 가장 최근 selector 값만을 보관하여 메모리에 부하를 줄일 수 있게 된다.