I have an application where I show a set of invites, each invite has a set of answers connected, that the users can update,
I have the following recoil state:
export const answerState = atom<AnswerDto[] | undefined>({
key: 'Answers',
default: selector({
key: 'Answers/Default',
get: async ({ get }) => {
const id = get(currentInviteIdState)
if (!id) {
return undefined
}
const response = await getAnswerInviteId(id)
return response.data
},
}),
})
Updating the states is done with a react useCallback(), like:
export function useUpdateAnswer() {
const [currentState, setState] = useRecoilState(answerState)
return useCallback(
(answer: AnswerDto) => {
postAnswerUpdate(answer).then(({ data }) =>
setState([
...(currentState?.filter((item) => item.id !== data.id) || []),
data,
]),
)
},
[currentState, setState],
)
}
this part does work fine, I can update the AnswerState, and get the result shown in my app. But if I then update the initial currentInviteIdState
, after I have updated a couple of answers, recoil doesn't fetch a new set of answers for this new invite.
It seems that this is as designed, according to https://recoiljs.org/docs/guides/asynchronous-data-queries#query-default-atom-values, so what am I doing wrong? I've been browsing through the docs for examples, but so far without any luck.
Should have read the documentation better.. Using atomFamily and selectorFamily let me do what I want, as I can specify an id.
const answerState = atomFamily<AnswerDto[] | undefined, number>({
key: 'Answers',
default: selectorFamily({
key: 'Answers/Default',
get: (id) => ({ get }) => {
if (!id) {
return undefined
}
return getAnswerInviteId(id).then(({data}) => data)
},
}),
})
export const answersByOtherState = selector({
key: 'answersbyId',
get: ({get}) => {
const id = get(currentInviteId)
return get(AnswerState(id))
}
})