react-nativereduxexporedux-toolkit

Error with Redux Toolkit createSlice function in React Native (EXPO)


I'm encountering an issue in my Expo project where I get the following error:

 TypeError: 0, _toolkit.createSlice is not a function (it is undefined), js engine: hermes
    at ContextNavigator (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.reportAdd.app&modulesOnly=false&runModule=true:153417:24)
    at ExpoRoot (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.reportAdd.app&modulesOnly=false&runModule=true:153388:30)
    at App
    at withDevTools(App) (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.reportAdd.app&modulesOnly=false&runModule=true:132684:27)
    at ErrorToastContainer (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.reportAdd.app&modulesOnly=false&runModule=true:132585:24)
    at ErrorOverlay
    at RCTView
    at View (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.reportAdd.app&modulesOnly=false&runModule=true:40235:43)
    at RCTView
    at View (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.reportAdd.app&modulesOnly=false&runModule=true:40235:43)
    at AppContainer (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.reportAdd.app&modulesOnly=false&runModule=true:40075:36)
    at main(RootComponent) (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.reportAdd.app&modulesOnly=false&runModule=true:121767:28)

Details:

Environment: Expo ( SDK 49 ) Error Message: TypeError: 0, _toolkit.createSlice is not a function (it is undefined), js engine: hermes.

Redux packages installed "react-redux": "^9.0.4", "redux-persist": "^6.0.0", "@reduxjs/toolkit": "^2.0.1",

File causing the error

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { RootState } from "../store";

type initialStateTypes = {
  notificationToken: string;
  hasCreatedAccount: boolean;
  currentPhoneNumber?: string;
};


const initialState: initialStateTypes = {
  notificationToken: "",
  hasCreatedAccount: false,
  currentPhoneNumber: "",
};

const appSlice = createSlice({
  name: "app",
  initialState,
  reducers: {

    setNotificationToken: (state, action: PayloadAction<string>) => {
      state.notificationToken = action.payload;
    },

    setHasCreatedAccount: (state, action: PayloadAction<boolean>) => {
      state.hasCreatedAccount = action.payload;
    },

    setCurrentPhoneNumber: (state, action) => {
      state.currentPhoneNumber = action.payload;
    },

    clear() {
      // Note that this should be left intentionally empty.
      // Clearing redux state and localForage happens in rootReducer.ts.
    },
  },
});

// Extract the action creators object and the reducer.
const { actions, reducer } = appSlice;

// Extract and export each action creator by name.
export const {
  setNotificationToken,
  setHasCreatedAccount,
  setCurrentPhoneNumber,
  clear,
} = actions;


export const selectNotificationToken = (state: RootState) =>
  state.app.notificationToken;
  
export const selectHasCreatedAccount = (state: RootState) =>
  state.app.hasCreatedAccount;


  // Export the reducer, either as a default.
export default reducer;

Solution

  • The error results from a metro bundler problem handling the .cjs extension common to dependencies. Unfortunately, .cjs isn't the only one, there's .mjs etc.

    In my case the .cjs was at play. The solution was to have my metro.config.js file looking as follows:

    // Learn more https://docs.expo.io/guides/customizing-metro
    const { getDefaultConfig } = require("@expo/metro-config");
    
    /** @type {import('expo/metro-config').MetroConfig} */
    const config = getDefaultConfig(__dirname);
    
    // What I had initially, was affecting `getReactNativePersistence`-import {
    // initializeAuth, getReactNativePersistence } from "firebase/auth"; as well
    // config.resolver.assetExts.push("cjs");
    
    //Fixes
    // config.resolver.sourceExts.push("cjs");
    
    // config.resolver.sourceExts = process.env.RN_SRC_EXT
    //   ? [
    //       ...process.env.RN_SRC_EXT.split(",").concat(config.resolver.sourceExts),
    //       "cjs",
    //     ] // <-- cjs added here
    //   : [...config.resolver.sourceExts, "cjs"]; // <-- cjs added here
    
    config.resolver.sourceExts.push("js", "json", "ts", "tsx", "cjs");
    
    module.exports = config;
    

    Play around with the commented segments under the fixes comment and see what works for you.

    If the above doesn't work, there are a couple of suggested solutions: