I would like to encapsulate the logic for a function to send push notifications so that it can be called from anywhere in the app. The push notifications API requires a jwtToken to be passed in the header. I want to call useContext on the AuthContextProvider to extract the token but the rules of hooks don't allow my function to call useContext since it isn't a React function component.
import React, { useContext } from "react";
import { AuthContext } from "@context/AuthContextProvider";
export const sendPushNotification = async function (notificationObject) {
const { authData } = useContext(AuthContext); //**<-- Fails with hooks error**
const authToken = authData.signInUserSession.idToken.jwtToken;
...
Here is the code that calls the function:
function AddToDoScreen() {
...
function handleSubmitAsync() {
...
let pushNotificationObject = {
profileIDs: [values.profileID],
title: "Push Notification Title",
body: "Push Notification Message",
};
sendPushNotification(pushNotificationObject);
I think this can be accomplished with a custom hook, but I'm not sure how. I tried starting the function name with use, but that didn't help.
Any pointers on how to implement this so I don't have to get the IdToken in each function that wants to call the sendPushNotification function?
BTW, I know you can't call Hooks inside nested functions. I tried moving the code up into the AddToDoScreen function but got the same error.
You've basically two options here:
Create a custom hook that encapsulates all the logic and returns a callback function a component can invoke.
import React, { useCallback, useContext } from "react";
import { AuthContext } from "@context/AuthContextProvider";
export const usePushNotification = () => {
const { authData } = useContext(AuthContext);
const authToken = authData.signInUserSession.idToken.jwtToken;
const sendPushNotification = useCallback(async (notificationObject) => {
... logic to use token and notification object and send push ...
}, [authToken]);
return {
sendPushNotification
};
};
function AddToDoScreen() {
const { sendPushNotification } = usePushNotification();
...
function handleSubmitAsync() {
...
const notification = {
profileIDs: [values.profileID],
title: "Push Notification Title",
body: "Push Notification Message",
};
sendPushNotification(notification);
}
...
}
Access the authToken value from the context in the React component and pass it to the callback function.
export const sendPushNotification = async ({
authToken,
notification,
}) => {
... logic to use token and notification object and send push ...
};
function AddToDoScreen() {
const { authData } = useContext(AuthContext);
const authToken = authData.signInUserSession.idToken.jwtToken;
...
function handleSubmitAsync() {
...
const notification = {
profileIDs: [values.profileID],
title: "Push Notification Title",
body: "Push Notification Message",
};
sendPushNotification({
authToken,
notification,
});
}
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With