reactjsnext.jsreact-modalswr

How to revalidate data on react-modal close with SWR?


I am trying to revalidate the data on react-modal close using SWR in a NextJS project.

I am using the SWR hook like so.


  const { data, error, isValidating } = useSWR(
    process.env.NEXT_PUBLIC_APP_URL + `/api/users`,
    fetcher,{
    revalidateIfStale: true,
    revalidateOnFocus: true,
    revalidateOnMount:true, 
   }
  );


  useEffect(() => {
    if (data) {
      setUsers(data.users);
    }
  }, [data, isValidating, users]);

//handle loading..
//handle error..


  return (
    <main className="mx-auto max-w-7xl ">
      <Header title="All users"/>
      <UsersList users={users} />
    </main>
  );

I am fetching a list of users and displaying them.

  const usersList = users.((user) => (
    <div className="space-x-5 text-sm" key={user.id}>
      {user.name}
      <DisableModal id={user.id} isDisabled={user.active}/>
    </div>
  ));

I have a react modal that allows us to disable the users, once I have disabled the users with handle click.

When the modal closes the data is not being refetched. This is a sample modal from the docs.

When I close the modal, and can see the list of users. They are not refreshed and not using revalidations with use SWR.


export const DisableModal = ({
  id,
  isDisabled,
}) => {
  const [disableModalIsOpen, setDisableModalIsOpen] = useState(false);

  function closeDisableModal() {
    setDisableModalIsOpen(false);
  }

  function openPublishModal() {
    setDisableModalIsOpen(true);
  }

  const handleDisableUser = async () => {
  //disable logic in rest call.
   closeDisableModal();
  }
....
}

Solution

  • You can revalidate the data manually using mutate when the onAfterClose callback in the modal gets triggered.

    export const DisableModal = () => {
        const [showModal, setShowModal] = useState(false);
        const { mutate } = useSWRConfig()
    
        return (
            <>
                <button onClick={() => { setShowModal(true) }}>Trigger Modal</button>
                <ReactModal 
                    isOpen={showModal}
                    onAfterClose={() => { 
                        mutate(process.env.NEXT_PUBLIC_APP_URL + '/api/users') 
                    }}
                    contentLabel="Minimal Modal Example"
                >
                    <button onClick={() => { setShowModal(false) }}>Close Modal</button>
                </ReactModal>
            </>
        )
    }
    

    Calling mutate(process.env.NEXT_PUBLIC_APP_URL + '/api/users') will broadcast a revalidation message to SWR hook with that given key. Meaning the useSWR(process.env.NEXT_PUBLIC_APP_URL + '/api/users', fetcher, { ... }) hook will re-run and return the updated users data.