-
I am currently studying how to avoid unnecessary re-rendering in the state management pattern using useContext+useReducer using jotai and recoil.
Here are the sandboxes for each using jotai and recoil. In the case of Recoil, I was able to avoid unnecessary re-rendering by using Atom that has article list as state and Atom that has article itself as state using const articlesState = atom<Article[]>({
key: "articlesState",
default: [
{
id: "1",
contents: "this is the first article",
likes: 0
},
{
id: "2",
contents: "this one is the second",
likes: 0
}
]
});
const articleState = selectorFamily<Article | undefined, { articleId: string }>(
{
key: "articleState",
get: ({ articleId }) => ({ get }) => {
const articles = get(articlesState);
return articles.find((article) => article.id === articleId);
},
set: ({ articleId }) => ({ set, get }, newValue) => {
if (!newValue) return;
const articles = get(articlesState);
const updatedArticles = articles.map((article) => {
if (article.id !== articleId) return article;
return newValue;
}) as Article[];
set(articlesState, updatedArticles);
}
}
); I expected to get the same result in Jotai by replacing Recoil's const articlesState = atom<Article[]>([
{
id: "1",
contents: "this is the first article",
likes: 0
},
{
id: "2",
contents: "this one is the second",
likes: 0
}
]);
const articleState = atomFamily<
{ articleId: string },
Article | undefined,
Article
>(
({ articleId }) =>
atom(
(get) => get(articlesState).find((article) => article.id === articleId),
(get, set, update) => {
const articles = get(articlesState);
const updatedArticles = articles.map((article) => {
if (article.id !== articleId) return article;
return update;
});
set(articlesState, updatedArticles);
}
),
(a, b) => a.articleId === b.articleId
);
(clicked: article 1 -> 2 -> 1) I think my understanding of jotai is bad, but how can I improve it? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Jotai takes some different approaches from Recoil.
You want to check the behavior of commits with useEffect. Double render with one commit is an expected/intentional behavior. See also: #627 |
Beta Was this translation helpful? Give feedback.
Jotai takes some different approaches from Recoil.
They are the following in the order of my preference:
splitAtom
utilatomFamily
which should work with the Recoil mental modelYou want to check the behavior of commits with useEffect.
https://codesandbox.io/s/with-jotai-forked-g814z?file=/src/Article.tsx
Double render with one commit is an expected/intentional behavior. See also: #627