Zain Khan
Zain Khan

Reputation: 1814

Facing Issue : Warning: React.createElement: type is invalid -- expected a string

I'm using useReducer, Context and Provider in my app but I'm facing this issue please anyone faced this issue so please let me know the solution for it

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s%s, undefined, You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check your code at App.js:20., in _default (at withExpoRoot.js:20) in RootErrorBoundary (at withExpoRoot.js:19) in ExpoRootComponent (at renderApplication.js:35) in RCTView (at View.js:45) in View (at AppContainer.js:98) in RCTView (at View.js:45) in View (at AppContainer.js:115) in AppContainer (at renderApplication.js:34) - node_modules\react-native\Libraries\YellowBox\YellowBox.js:59:8 in error - node_modules\expo\build\environment\muteWarnings.fx.js:26:24 in error - node_modules\react\cjs\react.development.js:188:36 in warningWithoutStack - node_modules\react\cjs\react.development.js:603:32 in warning - node_modules\react\cjs\react.development.js:1730:14 in createElementWithValidation * App.js:20:5 in _default - node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:9473:27 in renderWithHooks - node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:11994:6 in mountIndeterminateComponent - ... 18 more stack frames from framework internals

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s%s, undefined, You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check your code at App.js:20., in _default (at withExpoRoot.js:20) in RootErrorBoundary (at withExpoRoot.js:19) in ExpoRootComponent (at renderApplication.js:35) in RCTView (at View.js:45) in View (at AppContainer.js:98) in RCTView (at View.js:45) in View (at AppContainer.js:115) in AppContainer (at renderApplication.js:34) - node_modules\react-native\Libraries\YellowBox\YellowBox.js:59:8 in error - node_modules\expo\build\environment\muteWarnings.fx.js:26:24 in error - node_modules\react\cjs\react.development.js:188:36 in warningWithoutStack - node_modules\react\cjs\react.development.js:603:32 in warning - node_modules\react\cjs\react.development.js:1730:14 in createElementWithValidation * App.js:20:5 in _default - node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:9473:27 in renderWithHooks - node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:11994:6 in mountIndeterminateComponent - ... 21 more stack frames from framework internals

Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of _default. - node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:5716:10 in createFiberFromTypeAndProps - node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:5744:4 in createFiberFromElement - ... 22 more stack frames from framework internals

Warning: %s: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI., RootErrorBoundary - node_modules\react-native\Libraries\YellowBox\YellowBox.js:59:8 in error - node_modules\expo\build\environment\muteWarnings.fx.js:26:24 in error - ... 28 more stack frames from framework internals

App.js

import React from 'react';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import IndexScreen from './src/screens/IndexScreen';
import { Provider } from './src/context/BlogContext';

const navigator = createStackNavigator({
  Index: IndexScreen
}, {
  initialRouteName: 'Index',
  defaultNavigationOptions: {
    title: 'Blogs'
  }
});

const App = createAppContainer(navigator);

export default () => {
  return (
    <Provider>
      <App />
    </Provider>
  );
};

BlogContext.js

import React, { useReducer } from 'react';

    export default (reducer, actions, initialState) => {
         const Context = React.createContext();

         const Provider = ({ children }) => {
             const [state, dispatch] = useReducer(reducer, initialState);

             const boundActions = {};
             for(let key in actions){
                 boundActions[key] = actions[key](dispatch);
             }

             return(
                 <Context.Provider value={{state, ...boundActions}}>
                     {children}
                 </Context.Provider>
             );
         }

         return(Context, Provider);

    };

Upvotes: 0

Views: 9573

Answers (1)

Ga&#235;l S
Ga&#235;l S

Reputation: 1599

You have an issue regarding BlogContext. You are not using it correctly. You export it as default a function while in App.js, you use a named import.

BlogContext should be like this:

import React, { useReducer } from 'react';

    export default (reducer, actions, initialState) => {
         const Context = React.createContext();

         const Provider = ({ children }) => {
             const [state, dispatch] = useReducer(reducer, initialState);

             const boundActions = {};
             for(let key in actions){
                 boundActions[key] = actions[key](dispatch);
             }

             return(
                 <Context.Provider value={{state, ...boundActions}}>
                     {children}
                 </Context.Provider>
             );
         }

         //return an object with two keys
         return {Context, Provider};

    };

and App.js should use that accordingly:


import blogContext from './src/context/BlogContext';
/**
 ...code ... 
**/
//here you create your provider by calling the function imported from BlogContext
//with the expected arguments
const { Provider } = blogContext(reducer, actions, initialState)

/**

**/

export default () => {
  return (
    <Provider>
      <App />
    </Provider>
  );
};

Upvotes: 1

Related Questions