Selectors Family in Recoil for Statement Management — Nextjs

Selectors Family in Recoil for Statement Management — Nextjs

·

3 min read

Welcome friends. This blog post will teach you how to use the recoil selectors family for state management.

Video for those who understand Hindi: https://youtu.be/GJUq2PkGJWs

How to use atoms in recoil

How to use Recoil Selectors in Nextjs

🤯Selectors vs SelectorFamily

When you use selectors, you cannot pass any parameters for doing some logical work. But when you use selectors Family, you can pass a param and can have a logic.

Example 👇

🤔Situation

Suppose, you have a to-do list website.

Example of the website:

In simple words, you enter the id of a todo that you want to edit. Then using the recoil selector family, we can get the data of specific todo by passing id as a param.

Then you have made the atoms for it 👇.

import {atom} from 'recoil';

// this atom will store the current input of the user.
export const dataAtom = atom<number>({
  key: "data",
  default: 1,
});

// this atom will store the list of all todos.
export const todosAtom = atom<
  { userId: number; id: number; title: string; completed: boolean }[]
>({
  key: "todos",
  default: [
    {
      userId: 1,
      id: 1,
      title: "delectus aut autem",
      completed: false,
    },
    {
      userId: 1,
      id: 2,
      title: "quis ut nam facilis et officia qui",
      completed: false,
    },
    {
      userId: 1,
      id: 3,
      title: "fugiat veniam minus",
      completed: false,
    },
    {
      userId: 1,
      id: 4,
      title: "et porro tempora",
      completed: true,
    },
    {
      userId: 1,
      id: 5,
      title: "laboriosam mollitia et enim quasi adipisci quia provident illum",
      completed: false,
    },
    {
      userId: 1,
      id: 6,
      title: "qui ullam ratione quibusdam voluptatem quia omnis",
      completed: false,
    },
    {
      userId: 1,
      id: 7,
      title: "illo expedita consequatur quia in",
      completed: false,
    },
  ],
});

Index.tsx file 👇

import type { NextPage } from "next";
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
import { dataAtom } from "../atoms/atoms";
import Box from "../components/Box";

const Home: NextPage = () => {
  // This will give us ability to get and change the value of the input of the user.
  const [data, setData] = useRecoilState<number>(dataAtom);

  return (
    <div className="flex min-h-screen flex-col items-center justify-center py-2">
      <p className="text-md">
        Put the id of the todo in inputbox which you want to edit.
      </p>
      <input
        type="number"
        className="text-xl outline-none border-2 focus:border-purple-500 p-3 rounded-full duration-150"
        placeholder="Enter a value"
        value={data}
        onChange={(e) => setData(parseInt(e.target.value))}
      />

      {/* This is a box component for showing the title of the todo. */}
      <Box />
    </div>
  );
};

export default Home;

This is your selectors file.

import { DefaultValue, selectorFamily } from "recoil";
import { todosAtom } from "../atoms/atoms";

// selector Family
export const todosSelector = selectorFamily({
  key: "todosSelect",
  // this is return the specific todo when given it's id
  get:
    (id: number) =>
    ({ get }) => {
      const todos = get(todosAtom);

      // id
      const todo = todos.find((item) => item.id === id);

      return todo;
    },
  // this will help us set the data of the specific todo
  set:
    (id: number) =>
    ({ get, set }, newValue) => {
      const todos = get(todosAtom);

      const todoIndex = todos.findIndex((item) => item.id === id);

      const newTodos = [...todos];

      if (newValue instanceof DefaultValue) {
        return newTodos[todoIndex];
      } else if (newValue === undefined) {
        return newTodos[todoIndex];
      }

      newTodos[todoIndex] = newValue;

      set(todosAtom, newTodos);
    },
});

Now, let’s go to box.tsx file 👇


import React from "react";
import { useRecoilState, useRecoilValue } from "recoil";
import { dataAtom } from "../atoms/atoms";
import { todosSelector } from "../selectors/selectors";

function Box() {
  // The current todo id which user has entered
  const data = useRecoilValue(dataAtom);
  // Data of specific todo
  const [todo, setTodo] = useRecoilState(todosSelector(data));

  return (
    <div className="bg-slate-100 rounded-lg p-5 mt-5">
      <h1 className="text-xl mb-2">Todo: {data}</h1>

      <input
        type="text"
        placeholder="title"
        value={todo?.title}
        // 👇 this function gives us power to change the specific todo data.
        onChange={(e) => {
          setTodo({
            ...todo,
            title: e.target.value,
          } as any);
        }}
      />
    </div>
  );
}

export default Box;

Still any doubt 🤔. You can join our discord channel👇 Join the Next Dev Discord Server!

Did you find this article valuable?

Support Next Dev by becoming a sponsor. Any amount is appreciated!