React Native: Invalid Element Type Error
The "Element type is invalid" error is a common React Native issue that occurs when the framework receives an unexpected value instead of a valid component. This comprehensive guide covers the causes and solutions for this frustrating error.
Understanding the Error
Error: Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: object.
You likely forgot to export your component from the file it's defined in,
or you might have mixed up default and named imports.
This error typically indicates that React received something other than:
- A string (for built-in components like 'View', 'Text')
- A function/class (for custom components)
- A valid React element
Common Causes and Solutions
1. Import/Export Mismatch (Most Common)
The most frequent cause is confusion between default and named exports.
Named vs Default Exports
Named Export (multiple per file):
// Component file
export const CustomInput = () => {
return <Text>Input</Text>;
}
// Import with braces
import { CustomInput } from '../../components/CustomInput';
Default Export (one per file):
// Component file
const CustomInput = () => {
return <Text>Input</Text>;
}
export default CustomInput;
// Import without braces
import CustomInput from '../../components/CustomInput';
WARNING
Mixing these import/export patterns will result in undefined
values and trigger the error.
2. Incorrect File Paths
Double-check your import paths for typos or incorrect directory navigation:
// ❌ Incorrect - likely typo in "assetss"
import Logo from '../../../assetss/images/logo.png';
// ✅ Correct - verify the actual folder structure
import Logo from '../../../assets/images/logo.png';
3. File Extension Issues
Some environments require explicit file extensions:
// May be needed in some configurations
import CustomInput from '../../components/CustomInput/CustomInput.js';
4. IDE Auto-Import Errors
IDEs sometimes generate incorrect import statements:
// ❌ Incorrect default import (if library uses named exports)
import Modal from '@fluentui/react/lib/Modal';
// ✅ Correct named import
import { Modal } from '@fluentui/react/lib/Modal';
TIP
Always verify auto-generated imports match the library's export pattern.
5. Unsaved Files
If you're not using autosave, ensure all component files are saved before testing. Unsaved changes won't be reflected in your running application.
6. Node Module Corruption
Sometimes dependencies can become corrupted:
// package.json
"scripts": {
"install:clean": "rm -rf node_modules && rm -f package-lock.json && npm install"
}
Run npm run install:clean
to clear and reinstall dependencies.
7. Case Sensitivity Issues
File systems are case-sensitive on some platforms:
// ❌ Might fail on case-sensitive systems
import CustomInput from '../../components/custominput';
// ✅ Use exact case matching
import CustomInput from '../../components/CustomInput';
Debugging Techniques
1. Isolate the Problem Component
Temporarily remove components until the error disappears, then gradually add them back to identify the culprit.
2. Console Log Checks
Add debug statements to verify imports:
import CustomInput from '../../components/CustomInput';
console.log('CustomInput value:', CustomInput); // Should be a function/class, not undefined
3. Restart Development Environment
Sometimes a simple restart can resolve transient issues:
- Restart the Metro bundler:
npm start -- --reset-cache
- Reload your IDE/editor
- Restart the development server completely
Special Cases
Testing Environment Issues
When using Jest, ensure proper mocking:
// ❌ Incorrect mocking returns object
jest.mock('./components/notes-list', () => {
return {
NotesList: () => <div>Hello World</div>,
};
});
// ✅ Correct mocking returns component directly
jest.mock('./components/notes-list', () => {
const NotesList = () => <div>Hello World</div>;
return NotesList;
});
Third-Party Library Version Pinning
Some libraries may introduce breaking changes:
// Pin specific versions to avoid unexpected updates
"react-icons": "4.3.1", // Instead of "^4.3.1"
Passing Components as Props
Pass component references, not rendered JSX:
// ❌ Incorrect - passing rendered component
<SomeComponent errorBoundary={<ErrorBoundary />} />
// ✅ Correct - passing component reference
<SomeComponent errorBoundary={ErrorBoundary} />
Best Practices
- Consistent Export Patterns: Choose either named or default exports consistently across your project
- Path Aliases: Use path aliases to avoid complex relative imports
- TypeScript: Add TypeScript for better import/export validation
- Code Organization: Keep related files in clearly organized directories
- Version Control: Regularly commit changes to avoid losing work from unsaved files
INFO
The error message specifically mentions checking the render method of SignInScreen
- this is your starting point for investigation.
When All Else Fails
If you've tried everything and still encounter the error:
- Clone Fresh: Delete node_modules and reinstall dependencies
- Version Check: Ensure consistent Node.js and npm versions across environments
- Environment: Verify development environment setup
- Community: Check React Native GitHub issues for similar problems
By methodically checking these potential issues, you'll usually identify and resolve the "Invalid element type" error, getting your React Native application back on track.