Home > Back-end >  React Native useContext Hooks Issue
React Native useContext Hooks Issue

Time:10-13

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.

CodePudding user response:

You've basically two options here:

  1. 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);
      }
    
      ...
    }
    
  2. 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,
        });
      }
    
      ...
    
    }
    
  • Related