0

I'm following a tutorial where they are making a clone of Spotify. And to avoid prop-drilling I'm using React Context-API to save and pull user data for that I first tried to get the user and token but in the console, I keep getting the error "Uncaught TypeError: Cannot read properties of undefined (reading 'user')"

I think the problem is that dispatch is not able to access user and token from useDataLayerValue() in App.js

App.js


const spotify = new SpotifyWebApi();

function App() {
  // const [token, setToken] = useState(null);
  const [{user, token}, dispatch] = useDataLayerValue();
  // const [state, dispatch] = useDataLayerValue();


  useEffect(() => {
    const hash = getTokenFromUrl();
    window.location.hash = "";
    const _token = hash.access_token;

    if (_token) {

      dispatch({
        type: "SET_TOKEN",
        token: _token,
      });
      
      // setToken(_token);
      spotify.setAccessToken(_token);

      spotify.getMe().then((user) => {
        dispatch({
          type: "SET_USER",
          user: user,
        });
      });
    }
  }, [dispatch]);

  // console.log("saved", state);
  // console.log("saved token", token);
  return <div className="App">{token ? <Player /> : <Login />}</div>;
}

export default App;

reducer.js

export const initialState = {
  user: null,
  playlist: [],
  playing: false,
  item: null,
  token: null,
};

const reducer = (state, action) => {
  console.log(action);

  switch (action.type) {
    case "SET_USER":
      return {
        ...state,
        user: action.user,
      };
    case "SET_TOKEN":
      return {
        ...state,
        token: action.token,
      };

    default:
      return state;
  }
};

export default reducer;

DataLayer.js

import React, { createContext, useReducer, useContext } from "react";

export const DataLayerContext = createContext();

export const DataLayer = ({ initialState, reducer, children }) => (
  <DataLayerContext.Provider value={useReducer(reducer, initialState)}>
    {children}
  </DataLayerContext.Provider>
);

export const useDataLayerValue = () => useContext(DataLayerContext);


In App.js Instead of

const [{user, token}, dispatch] = useDataLayerValue();

if a write

const [state, dispatch] = useDataLayerValue();

I can receive the user data in console but it doesn't work for token also sometimes I get error of:- "dispatch is not a function."

Michal Miky Jankovský
  • 3,089
  • 1
  • 35
  • 36

0 Answers0