How to fix React.memo requires a function component in React

ReactINTERMEDIATEMEDIUMUpdated Dec 10, 2025· 102 views

This error occurs when trying to wrap a non-component value with React.memo, such as class components, string literals, or other invalid types. React.memo is specifically designed for function components and expects a valid React component as its argument to enable memoization.

Quick fix

Fixes React.memo requires a function component

const MyValue = { name: 'test' };
const Memoized = React.memo(MyValue); // ❌ Error!
  1. Verify you're wrapping a function component with React.memo
  2. Convert class components to function components for memoization
  3. Ensure you're exporting the correct component
  4. Use forwardRef when memoizing components that receive refs
react — error
const MyValue = { name: 'test' };
const Memoized = React.memo(MyValue); // ❌ Error!
React.memo requires a function component

What this error means

React.memo is a higher-order component (HOC) that memoizes a component to prevent unnecessary re-renders when props haven't changed. However, it only works with valid React function components and forwardRef-wrapped components. When you pass something that isn't a valid component—such as a string, object, class component, or any other value—React cannot determine what to memoize and throws this error. The error represents a type mismatch between what React.memo expects (a function component or forwardRef) and what you're actually providing. React.memo needs a callable function that returns JSX to wrap with its memoization logic. Class components should use React.PureComponent or shouldComponentUpdate instead, as they have different lifecycle mechanisms that don't work with the memoization pattern React.memo implements. Understanding this error is important because React.memo is a performance optimization tool, and knowing its constraints helps you apply memoization correctly throughout your codebase.

Typical symptoms

  • Error message: "React.memo requires a function component"
  • Application fails to render a component that uses React.memo
  • Error occurs at component definition time, not during rendering
  • Wrapping a class component with React.memo produces the error
  • Attempting to export a memoized component that isn't a function fails
  • Error appears in browser console immediately when module loads
  • Build succeeds but runtime error appears before any component renders

Common causes

  1. Wrapping a class component with React.memo instead of extending PureComponent
  2. Passing a string, number, or other non-component value to React.memo
  3. Passing an object or configuration instead of a component function
  4. Forgetting to define the component as a function before wrapping with memo
  5. Accidentally passing React.forwardRef result to memo without proper wrapping
  6. Exporting the wrong value or intermediate result instead of the component
  7. Using memo with an imported non-component value or constant
  8. Passing a component before it's fully defined or exported

How to fix "React.memo requires a function component"

1Verify you're wrapping a function component with React.memo

Ensure that what you're passing to React.memo is a valid function component. The component must be a function that returns JSX.

Bad - Wrapping a non-component value:

javascript
const MyValue = { name: 'test' };
const Memoized = React.memo(MyValue); // ❌ Error!

Good - Wrapping a function component:

javascript
function MyComponent(props) {
  return <div>{props.name}</div>;
}
const Memoized = React.memo(MyComponent); // ✓ Correct

Also good - Arrow function component:

javascript
const MyComponent = (props) => {
  return <div>{props.name}</div>;
};
const Memoized = React.memo(MyComponent); // ✓ Correct
2Convert class components to function components for memoization

React.memo only works with function components. If you're trying to memoize a class component, use React.PureComponent or shouldComponentUpdate instead.

Bad - Trying to memo a class component:

javascript
class MyComponent extends React.Component {
  render() {
    return <div>{this.props.name}</div>;
  }
}
const Memoized = React.memo(MyComponent); // ❌ Error!

Good - Class component with PureComponent:

javascript
class MyComponent extends React.PureComponent {
  render() {
    return <div>{this.props.name}</div>;
  }
}

Good - Convert to function component with memo:

javascript
function MyComponent(props) {
  return <div>{props.name}</div>;
}
const Memoized = React.memo(MyComponent); // ✓ Correct

Good - Class with custom shouldComponentUpdate:

javascript
class MyComponent extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    return !Object.is(this.props, nextProps) || !Object.is(this.state, nextState);
  }
  
  render() {
    return <div>{this.props.name}</div>;
  }
}
3Ensure you're exporting the correct component

Verify that you're exporting the component function itself, not a configuration object or other value.

Bad - Exporting wrong value:

javascript
const config = { component: MyComponent };
export const Memoized = React.memo(config); // ❌ Error!

Good - Export the component:

javascript
function MyComponent(props) {
  return <div>{props.name}</div>;
}
export const Memoized = React.memo(MyComponent); // ✓ Correct

Good - Default export:

javascript
function MyComponent(props) {
  return <div>{props.name}</div>;
}
export default React.memo(MyComponent); // ✓ Correct

Good - Named export:

javascript
const MyComponent = (props) => <div>{props.name}</div>;
export const MemoizedComponent = React.memo(MyComponent); // ✓ Correct
4Use forwardRef when memoizing components that receive refs

If you need to memoize a component that receives a ref prop, wrap it with forwardRef first, then memo.

Bad - Trying to memo component with ref:

javascript
const MyComponent = (props, ref) => {
  return <input ref={ref} {...props} />;
};
const Memoized = React.memo(MyComponent); // ❌ Refs not forwarded

Good - forwardRef first, then memo:

javascript
const MyComponent = React.forwardRef((props, ref) => {
  return <input ref={ref} {...props} />;
});
const Memoized = React.memo(MyComponent); // ✓ Correct

Good - Single line:

javascript
const Memoized = React.memo(
  React.forwardRef((props, ref) => (
    <input ref={ref} {...props} />
  ))
);
5Check your imports are correct

Ensure you're importing React correctly and using React.memo, not a misspelled or incorrectly imported version.

Bad - Incorrect import:

javascript
import { memo } from 'react';
const MyComponent = () => <div>Hello</div>;
const Memoized = memo(myConfig); // If myConfig isn't a component

Good - Using React.memo:

javascript
import React from 'react';
const MyComponent = () => <div>Hello</div>;
const Memoized = React.memo(MyComponent); // ✓ Correct

Good - Importing memo directly:

javascript
import { memo } from 'react';
const MyComponent = () => <div>Hello</div>;
const Memoized = memo(MyComponent); // ✓ Correct
6Custom comparison function must be a function

React.memo's second argument is an optional custom comparison function. If you provide it, it must be a function that receives two props objects and returns a boolean.

Bad - Invalid comparison argument:

javascript
const MyComponent = (props) => <div>{props.name}</div>;
const Memoized = React.memo(MyComponent, { custom: true }); // ❌ Must be a function

Good - Custom comparison function:

javascript
const MyComponent = (props) => <div>{props.name}</div>;
const Memoized = React.memo(MyComponent, (prevProps, nextProps) => {
  return prevProps.id === nextProps.id; // Return true if props are equal
}); // ✓ Correct

Good - No custom comparison (default shallow comparison):

javascript
const MyComponent = (props) => <div>{props.name}</div>;
const Memoized = React.memo(MyComponent); // ✓ Correct
7Avoid wrapping children or dynamic values with memo

React.memo only memoizes the component itself, not what's inside it. Don't try to memo children props or context values.

Bad - Trying to memo children:

javascript
const MyComponent = (props) => {
  const MemoChild = React.memo(props.children); // ❌ Wrong!
  return <div>{MemoChild}</div>;
};

Good - Memoize the component that renders children:

javascript
const MyComponent = React.memo((props) => {
  return <div>{props.children}</div>;
}); // ✓ Correct - Component is memoized

Good - Extract children as separate memoized component:

javascript
const ChildRenderer = React.memo(({ children }) => (
  <div>{children}</div>
));

const MyComponent = (props) => {
  return <ChildRenderer>{props.children}</ChildRenderer>;
}; // ✓ Correct

Advanced notes

React.memo implements shallow comparison of props by default. This means if you pass new object or function references, the component will re-render even with the same logical values. Use useCallback for function props and useMemo for object props to maintain reference equality.

TypeScript Considerations: When using TypeScript with React.memo, the generic type parameters might not be preserved correctly. If you need strict typing, use an explicit type annotation:

typescript
interface MyComponentProps {
  name: string;
  age: number;
}

const MyComponent: React.FC<MyComponentProps> = (props) => {
  return <div>{props.name}</div>;
};

const Memoized = React.memo(MyComponent);

Performance Perspective: Not all components benefit from memoization. Use React.memo when:
- The component is pure (same props produce same output)
- The component re-renders frequently with the same props
- The component has expensive render logic

If a component rarely re-renders or always receives new props, memoization adds unnecessary overhead.

Composition Pattern: Instead of memoizing everything, consider moving state management to a parent component and keeping child components simple. Often, better component structure is more effective than memoization.

Testing Note: When testing memoized components, ensure your test setup correctly handles React.memo. Some testing libraries may not automatically unwrap memoized components, affecting test behavior.

Frequently asked questions

What does "React.memo requires a function component" mean?
memo is a higher-order component (HOC) that memoizes a component to prevent unnecessary re-renders when props haven't changed. However, it only works with valid React function components and forwardRef-wrapped components. When you pass something that isn't a valid component—such as a string, object, class component, or any other value—React cannot determine what to memoize and throws this error.
How do I fix "React.memo requires a function component"?
This error occurs when trying to wrap a non-component value with React.memo, such as class components, string literals, or other invalid types. React.memo is specifically designed for function components and expects a valid React component as its argument to enable memoization.
What causes "React.memo requires a function component"?
Wrapping a class component with React.memo instead of extending PureComponent Passing a string, number, or other non-component value to React.memo Passing an object or configuration instead of a component function
Is the "React.memo requires a function component" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading