Home > Enterprise >  Redux toolkit mutation access to state across multiple components
Redux toolkit mutation access to state across multiple components

Time:08-09

I'm start using RTQ. To access query data is possible via generated hook. But for mutations, it doesn't work.

I have this simple example.

This component is responsible for loading "users" from API.

const Page = () => {
    const {
        isSuccess: isSuccessUsers
        isLoading: isLoadingUsers
    } = useGetUsersQuery({})

    if (isLoadingUsers) return <LoadingSpinner />
    if (isSuccessUsers) return <UsersTable />
    ...
}

This component display users, which are obtained from cache - was filled by the API call in previous component "Page". Also in that component I want display loading spinner for deleting state.

const UsersTable = () => {
    const {
        data: dataUsers,
        isFetching: isFetchingUsers,
    } = useGetUsersQuery({})

    const [, {
        data: dataDeleteUser,
        isLoading: isLoadingDeleteUser,
        isSuccess: isSuccessDeleteUser,
        isError: isErrorDeleteUser,
        error: errorDeleteUser,
    }] = useDeleteUserMutation()

    useEffect(() => {
        if (isSuccess) {
            console.log(data.data.message)
        }
    }, [isSuccess])

     useEffect(() => {
        if (isError) {
            console.log(error.data.message)
        }
    }, [isError])

    if (usersIsFetching || isLoadingDeleteUser) return <LoadingSpinner />

    dataUsers.map(user=>(<UsersTableRow user={user}/>))
}

In this component I only want call delete function. But here, when use same pattern just like for query, it doesnt work.

const UsersTableRow = ({user}) => {
    const [deleteUser] = useDeleteUserMutation()

    const handleDeleUser = () => {
        deleteUser(user.id)
    }
    ...
}

I could solve this by pass deleteUser function as prop from UsersTable component to UsersTableRow component.

    const [ deleteUser, {
        data: dataDeleteUser,
        isLoading: isLoadingDeleteUser,
        isSuccess: isSuccessDeleteUser,
        isError: isErrorDeleteUser,
        error: errorDeleteUser,
    }] = useDeleteUserMutation()
dataUsers.map(user=>(<UsersTableRow deleteUser={deleteUser} user={user}/>))

I would like to avoid this, because if there are more child components, I will have to pass to every child. Is there some better solution?

CodePudding user response:

You can use a fixed cache key to "tell" redux-toolkit that you want to use the same result for both components:

export const ComponentOne = () => {
  // Triggering `deleteUser` will affect the result in both this component,
  // but as well as the result in `ComponentTwo`, and vice-versa
  const [deleteUser, result] = useDeleteUserMutation({
    fixedCacheKey: 'shared-delete-user',
  })

  return <div>...</div>
}

export const ComponentTwo = () => {
  const [deleteUser, result] = useDeleteUserMutation({
    fixedCacheKey: 'shared-delete-user',
  })

  return <div>...</div>
}
  • Related