React: How to Export a Pure Stateless Functional Component - Troubleshooting Guide

In React, components are the building blocks of your application. Among the various types of components, Pure Stateless Functional Components (PSFCs) stand out for their simplicity, reusability, and performance. These are functions that accept props and return JSX, with no internal state or lifecycle methods. However, even experienced developers can run into issues when exporting and importing these components—leading to errors like "Component is not defined" or "Nothing renders."

This guide dives deep into exporting PSFCs, common pitfalls, and step-by-step troubleshooting. Whether you’re a beginner or need a refresher, you’ll learn how to export components correctly, avoid mistakes, and debug issues efficiently.

Table of Contents#

  1. What is a Pure Stateless Functional Component (PSFC)?
  2. How to Export a PSFC
  3. Common Export Issues & Troubleshooting
  4. Troubleshooting Workflow
  5. Best Practices for Exporting PSFCs
  6. Conclusion
  7. References

What is a Pure Stateless Functional Component (PSFC)?#

A Pure Stateless Functional Component is a JavaScript function that:

  • Accepts props as input (optional).
  • Returns React elements (JSX).
  • Has no internal state (useState, useReducer, etc.).
  • Has no lifecycle methods (e.g., componentDidMount—though hooks like useEffect are allowed in modern functional components, but "pure" here emphasizes no side effects).
  • Is "pure": Given the same props, it always returns the same output (no side effects like API calls or state mutations).

Example of a PSFC:

// Greeting.jsx
const Greeting = (props) => {
  return <h1>Hello, {props.name || "Guest"}!</h1>;
};
 
// Or with function declaration syntax:
function Greeting(props) {
  return <h1>Hello, {props.name || "Guest"}!</h1>;
}

PSFCs are lightweight, easy to test, and optimize well with React’s rendering engine. But to reuse them across your app, you must export them correctly.

How to Export a PSFC#

React uses ES Modules (ESM) for exporting/importing components. There are two primary ways to export a PSFC: named exports and default exports.

Named Exports#

Named exports let you export multiple values from a file, each with a unique name. They are imported using curly braces {}.

Syntax:#

// Option 1: Export at declaration
export const Greeting = (props) => {
  return <h1>Hello, {props.name}!</h1>;
};
 
// Option 2: Export at the bottom (recommended for readability)
const Greeting = (props) => {
  return <h1>Hello, {props.name}!</h1>;
};
 
export { Greeting }; // Explicitly list exports

Importing a Named Export:#

// In AnotherComponent.jsx
import { Greeting } from './Greeting';
 
function AnotherComponent() {
  return <Greeting name="Alice" />;
}

Default Exports#

Default exports let you export a single "main" value from a file. A file can have only one default export. They are imported without curly braces.

Syntax:#

// Option 1: Export at declaration
export default function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>;
}
 
// Option 2: Export at the bottom (most common)
const Greeting = (props) => {
  return <h1>Hello, {props.name}!</h1>;
};
 
export default Greeting; // Mark as default

Importing a Default Export:#

// In AnotherComponent.jsx
import Greeting from './Greeting'; // No curly braces
 
function AnotherComponent() {
  return <Greeting name="Bob" />;
}

When to Use Named vs. Default Exports#

Named ExportsDefault Exports
Use when exporting multiple components/utils from a single file (e.g., Button.jsx exporting PrimaryButton and SecondaryButton).Use when a file exports a single primary component (e.g., Header.jsx exporting only Header).
Import requires exact name matching (curly braces).Import can use any name (though convention is to use the component’s name).
Explicit and self-documenting.Simpler syntax for single-component files.

Common Export Issues & Troubleshooting#

Even with correct syntax, exporting PSFCs can fail. Below are the most common issues and how to fix them.

Issue 1: Forgetting to Export the Component#

Problem: The component is defined but not exported. When imported, it will be undefined, leading to errors like:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

Example Mistake:

// Greeting.jsx (Mistake: No export!)
const Greeting = (props) => {
  return <h1>Hello, {props.name}!</h1>;
};
 
// Importing this will fail:
import Greeting from './Greeting'; // Greeting is undefined

Fix: Add an export (named or default):

// Greeting.jsx (Fixed)
const Greeting = (props) => {
  return <h1>Hello, {props.name}!</h1>;
};
 
export default Greeting; // Add default export
// OR export { Greeting }; (named export)

Issue 2: Mismatched Import/Export Syntax#

Problem: Using a named import for a default export (or vice versa). This causes undefined or Module not found errors.

Example Mistake 1: Default Export → Named Import

// Greeting.jsx (Default export)
export default function Greeting(props) {
  return <h1>Hello!</h1>;
}
 
// Importing with named syntax (Mistake)
import { Greeting } from './Greeting'; // ❌ Error: Greeting is not exported

Fix: Use default import syntax:

import Greeting from './Greeting'; // ✅ Correct (no curly braces)

Example Mistake 2: Named Export → Default Import

// Greeting.jsx (Named export)
export const Greeting = (props) => <h1>Hello!</h1>;
 
// Importing with default syntax (Mistake)
import Greeting from './Greeting'; // ❌ Greeting is undefined (imports the default export, which doesn’t exist)

Fix: Use named import syntax:

import { Greeting } from './Greeting'; // ✅ Correct (curly braces)

Issue 3: Typos in Component/Export Names#

Problem: Typos in the component name, export statement, or import path. React will throw errors like:
Error: Cannot find module './Greetng' (typo in filename) or Error: Greetng is not exported (typo in component name).

Example Mistake:

// Greeting.jsx (Component named "Greetng" by mistake)
export const Greetng = (props) => <h1>Hello!</h1>;
 
// Importing with correct name but component is misspelled
import { Greeting } from './Greeting'; // ❌ Error: Greeting is not exported

Fix: Ensure names and paths match exactly:

// Greeting.jsx (Fixed name)
export const Greeting = (props) => <h1>Hello!</h1>;
 
// Import with correct name
import { Greeting } from './Greeting'; // ✅ Correct

Issue 4: Exporting Non-Component Values#

Problem: Accidentally exporting an object, string, or non-function instead of the component. This causes errors like:
Error: Functions are not valid as a React child.

Example Mistake:

// Greeting.jsx (Exporting an object instead of the function)
const Greeting = (props) => <h1>Hello!</h1>;
 
export default { Greeting }; // ❌ Exports { Greeting: [Function] }, not the function itself

Fix: Export the function directly:

// Greeting.jsx (Fixed)
const Greeting = (props) => <h1>Hello!</h1>;
 
export default Greeting; // ✅ Exports the function

Issue 5: Default Exports with require (CommonJS)#

Problem: Using require (CommonJS syntax) to import a default export. Unlike ESM import, require returns an object with a default property for default exports.

Example Mistake:

// Greeting.jsx (Default export)
export default (props) => <h1>Hello!</h1>;
 
// Using require (Mistake)
const Greeting = require('./Greeting'); // ❌ Greeting is { default: [Function] }, not the component

Fix: Access the default property:

const Greeting = require('./Greeting').default; // ✅ Correct for CommonJS
// Or better: Use ESM `import` syntax instead of `require`.

Troubleshooting Workflow#

If your component isn’t importing/ rendering, follow these steps:

  1. Check if the component is exported: Open the component file and verify it has export (named or default).
  2. Verify import/export match: Ensure the import syntax ({ } or not) matches the export type (named or default).
  3. Check for typos: Compare the component name, filename, and import path for typos (case-sensitive!).
  4. Test with a minimal component: Create a simple test component (e.g., const Test = () => <div>Test</div>; export default Test;) and try importing it. If it works, the issue is in your original component’s logic.
  5. Check the browser console/terminal: Errors like Module not found or undefined often point to export/import mismatches.

Best Practices for Exporting PSFCs#

To avoid issues, follow these best practices:

  1. Be consistent: Stick to one export style per file (e.g., never mix named and default exports unless necessary).
  2. Name components: Always name PSFCs (e.g., const Greeting = () => {} instead of export default () => {}). Named components improve debugging (React DevTools shows the name instead of Anonymous).
  3. Avoid default exports for utility components: For small, reusable components (e.g., Icon), use named exports to make imports explicit:
    // Icons.jsx (Named exports for clarity)
    export const UserIcon = () => <svg>...</svg>;
    export const HomeIcon = () => <svg>...</svg>;
  4. Use ESLint rules: Enable rules like react/function-component-definition (to enforce named components) and import/named (to catch missing named exports).
  5. Document exports: Add comments or JSDoc to clarify exported components (e.g., /** Primary button component */ export const PrimaryButton = () => {}).

Conclusion#

Exporting Pure Stateless Functional Components correctly is critical for building maintainable React apps. By understanding named vs. default exports, avoiding common pitfalls like mismatched syntax or typos, and following best practices, you’ll reduce debugging time and ensure components work seamlessly across your application.

Remember: The key is consistency—choose an export style, stick to it, and validate with tools like ESLint. With these steps, you’ll master PSFC exports in no time!

References#