Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix nextCreate is not a function setting up useMemo setting up authentication react router and hooks

I'm trying to use context to create a authentication provider for my app. Following a guide for Authentication with react router and react hooks. It's using a memo to fetch authentication if auth changes.

This is the guide i was following https://medium.com/trabe/implementing-private-routes-with-react-router-and-hooks-ed38d0cf93d5

I've tried looking up the error and working around the memo to no avail.

Here is my provider

const AuthDataContext = createContext(null)

const initialAuthData = {}

const AuthDataProvider = props => {
  const [authData, setAuthData] = useState(initialAuthData)

  useEffect(() => {
    async function getAuth(){
      let currentAuthData = await fetch("URL/api/v1/logged_in", {
        method: "GET",
        credentials: "include",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json"
        }
      })
        .then(res => res.json())
        .then(data => (data))
        .catch(error => console.error("Error:", error));

        if(currentAuthData) {
          setAuthData(currentAuthData)
        }
    };
    getAuth()
  },[])

  const onLogout = () => setAuthData(initialAuthData);

  const onLogin = newAuthData => setAuthData(newAuthData);

  const authDataValue = useMemo({ ...authData, onLogin, onLogout }, [authData]);
  return <AuthDataContext.Provider value={authDataValue} {...props} />;
};

export const useAuthDataContext = () => useContext(AuthDataContext);

The PrivateRoute component

const PrivateRoute = ({ component, ...options }) => {
  const { user } = useAuthDataContext();
  const finalComponent = user ? component : SignInPage;

  return <Route {...options} component={finalComponent} />;
};

The AuthProvider wrapping my app

const MyApp = props => (
    <BrowserRouter>
      <AuthDataProvider>
        <App />
      </AuthDataProvider>
    </BrowserRouter>
);

I expected the auth provider to fetch the user and Logged_In status and provide it to child components. The private route to see the authData from the context api and only render the route if the user is logged in. Thanks in advance!

The useMemo is throwing this error nextCreate is not a function mountMemo

 13962 |   var hook = mountWorkInProgressHook();
 13963 |   var nextDeps = deps === undefined ? null : deps;
> 13964 |   var nextValue = nextCreate();
       | ^  13965 |   hook.memoizedState = [nextValue, nextDeps];
 13966 |   return nextValue;
 13967 | }

View compiled

like image 624
Logan Klein Avatar asked Jul 08 '19 22:07

Logan Klein


People also ask

How do you use useMemo in React hooks?

Use useMemo To fix this performance issue, we can use the useMemo Hook to memoize the expensiveCalculation function. This will cause the function to only run when needed. We can wrap the expensive function call with useMemo . The useMemo Hook accepts a second parameter to declare dependencies.

Is useMemo a built-in React hook?

React has a built-in hook called useMemo that allows you to memoize expensive functions so that you can avoid calling them on every render. You simple pass in a function and an array of inputs and useMemo will only recompute the memoized value when one of the inputs has changed.

What is useMemo in React hooks?

The useMemo is a hook used in the functional component of react that returns a memoized value. In Computer Science, memoization is a concept used in general when we don't need to recompute the function with a given argument for the next time as it returns the cached result.

How do you use useMemo and useCallback in React?

useMemo is very similar to useCallback. It accepts a function and a list of dependencies, but the difference between useMemo and useCallback is that useMemo returns the memo-ized value returned by the passed function. It only recalculates the value when one of the dependencies changes.


2 Answers

The "nextCreate is not a function" error is thrown when you're not passing a function as a useMemo() argument. For example, useMemo(123, []) will throw and useMemo(() => 123, []) won't.

like image 120
catamphetamine Avatar answered Oct 06 '22 07:10

catamphetamine


You don't need to use useMemo. It will duplicate what Provider already accomplishes. Instead

return <AuthDataContext.Provider value={{ authData, onLogin, onLogout }} {...props} />;
like image 23
SILENT Avatar answered Oct 06 '22 07:10

SILENT