0
  1. My goal is to use custom hooks created from Context to pass and modify stored values
  2. The final goal is to use something like useFeedContext() to get or modify the context values
  3. What I am actually getting is either the functions that I call are undefined or some other problem ( I tried multiple approaches)

I tried following this video basics of react context in conjunction with this thread How to change Context value while using React Hook of useContext but I am clearly getting something wrong.

Here is what I tried :

return part of App.js

    <FeedProvider mf={/* what do i put here  */}>
      <Navigation>
        <HomeScreen />
        <ParsedFeed />
        <FavScreen />
      </Navigation>
    </FeedProvider>

Main provider logic

import React, { useState, useEffect, useContext, useCallback } from "react";
import AsyncStorage from "@react-native-async-storage/async-storage";

const FeedContext = React.createContext();

const defaultFeed = [];


const getData = async (keyName) => {
  try {
    const jsonValue = await AsyncStorage.getItem(keyName);
    return jsonValue != null ? JSON.parse(jsonValue) : null;
  } catch (e) {
    console.log(e);
  }
};
const storeData = async (value, keyName) => {
  console.log(value, keyName);
  try {
    const jsonValue = JSON.stringify(value);
    await AsyncStorage.setItem(keyName, jsonValue);
  } catch (e) {
    console.log(e);
  }
};

export const FeedProvider = ({ children, mf }) => {
  const [mainFeed, setMainFeed] = useState(mf || defaultFeed);
  const [feedLoaded, setFeedLoaded] = useState(false);

  let load = async () => {
    let temp = await AsyncStorage.getItem("mainUserFeed");
    temp != null
      ? getData("mainUserFeed").then((loadedFeed) => setMainFeed(loadedFeed))
      : setMainFeed(defaultFeed);
    setFeedLoaded(true);
  };
  useEffect(() => {
    load();
  }, []);

  useCallback(async () => {
    if (!feedLoaded) {
      return await load();
    }
  }, [mainFeed]);

  const setFeed = (obj) => {
    setMainFeed(obj);
    storeData(mainFeed, "mainUserFeed");
  };

  return (
    <FeedContext.Provider value={{ getFeed: mainFeed, setFeed }}>
      {children}
    </FeedContext.Provider>
  );
};

//export const FeedConsumer = FeedContext.Consumer;

export default FeedContext;

The custom hook

import { useContext } from "react";
import FeedContext from "./feedProviderContext";

export default function useFeedContext() {
  const context = useContext(FeedContext);

  return context;
}

What I would hope for is the ability to call the useFeedContext hook anywhere in the app after import like:

let myhook = useFeedContext() 

console.log(myhook.getFeed) /// returns the context of the mainFeed from the provider
myhook.setFeed([{test:1},{test:2}]) /// would update the mainFeed from the provider so that mainFeed  is set to the passed array with two objects. 

I hope this all makes sense, I have spend way longer that I am comfortable to admit so any help is much appreciated.

1 Answers1

1

If you want to keep using your useFeedContext function, I suggest to move it into the your 'Provider Logic' or I'd call it as 'FeedContext.tsx'

FeedContext.tsx

const FeedContext = createContext({});
export const useFeedContext = () => {
  return useContext(FeedContext);
}

export const AuthProvider = ({children}) => {
  const [mainFeed, setMainFeed] = useState(mf || defaultFeed);
  ...
  return (
    <FeedContext.Provider value={{mainFeed, setMainFeed}}>
      {children}
    </FeedContext.Provider>
  );
};

YourScreen.tsx

const YourScreen = () => {
  const {mainFeed, setMainFeed} = useFeedContext();

  useEffect(() => {
    // You have to wait until mainFeed is defined, because it's asynchronous.
    if (!mainFeed || !mainFeed.length) {
      return;
    }

    // Do something here
    ...
  }, [mainFeed]);

  ...
  return (
    ...
  );
};

export default YourScreen;
Jeaf Gilbert
  • 11,495
  • 19
  • 78
  • 105
  • thank you so much ! I thought that the loop of useEffect and useCallback will be enough for the mainFeed to be loaded and therefore used in other screens. :D – Eggs_on_rocks Apr 12 '21 at 16:25