React is throwing a fit because you’re trying to render a JavaScript function directly into your JSX, and it has no idea what to do with it.
This usually happens when you’re passing a component function as a prop to another component, or when you’re trying to conditionally render something and accidentally include the function definition itself instead of the result of calling it. React expects to render actual elements, text, numbers, or arrays of these things, not the blueprints for creating them.
Here are the most common reasons this breaks and how to fix them:
1. Passing a Component Function as a Prop Instead of its Rendered Output
- Diagnosis: Look at the component that’s throwing the error. Find where you’re passing a prop that looks like
propName={MyComponent}. - Cause: You’re passing the function
MyComponentitself, not the result of callingMyComponent(). React can’t render a function. - Fix: Call the function when you pass it:
propName={<MyComponent />}. This tells React to executeMyComponentand render whatever it returns. - Why it works: You’re now passing a React element (the result of calling the component function), which React knows how to process and render into the DOM.
2. Incorrect Conditional Rendering with Functions
- Diagnosis: Examine your conditional rendering logic (using
&&,||, ternary operators, orifstatements outside of JSX). You might see something likecondition && MyComponentorcondition ? MyComponent : null. - Cause: Similar to the above, you’re passing the component function
MyComponentinstead of the element<MyComponent />. - Fix: Ensure you’re always calling the component function when you intend to render it:
condition && <MyComponent />orcondition ? <MyComponent /> : null. - Why it works: The
&&and ternary operators are evaluating a boolean condition and then returning either a React element ornull. React can render elements ornull(which renders nothing), but not raw functions.
3. Accidentally Returning a Function from a Render Method
- Diagnosis: If you’re writing a custom hook or a component that returns a value that’s then rendered, check the
returnstatement. - Cause: The function might be returning another function instead of a JSX element or a primitive value.
- Fix: Ensure the
returnstatement in your component or hook returns a valid React node:return <SomeElement />;orreturn <div>Hello</div>;orreturn someValue;. If you need to return a function for some advanced pattern, you’ll have to wrap it in an element or handle it differently before rendering. - Why it works: The
returnstatement must yield something React can understand as a renderable output.
4. Misunderstanding Higher-Order Components (HOCs) or Render Props
- Diagnosis: If you’re using libraries that employ HOCs or the render prop pattern, inspect how you’re applying them.
- Cause: You might be trying to render the HOC itself or a component that returns a function for its
renderprop, rather than the actual component that the HOC wraps or the result of the render prop function. - Fix: For HOCs, you usually call the HOC with your component and then render the result of that call:
const EnhancedComponent = withMyHoc(MyComponent); return <EnhancedComponent />;. For render props, ensure you’re calling the function passed to therenderprop:render={() => <MyComponent />}. - Why it works: You’re correctly instantiating the components or calling the functions that produce the renderable output.
5. Incorrect Use of React.createElement or JSX Compilation
- Diagnosis: If you’re not using JSX or are debugging transpilation issues, check how
React.createElementis being called. - Cause:
React.createElement(MyComponent, props)is the underlying call for<MyComponent {...props} />. If you accidentally passMyComponentas the second argument (props) or if the first argument itself is a function that’s not meant to be an element type, you’ll see this. More commonly, if you were to writeReact.createElement(functionThatReturnsAFunction, {})this would be the issue. - Fix: Ensure the first argument to
React.createElementis a valid React component type (a string for DOM elements like'div', or a function/class for React components).React.createElement(MyComponent, props)is correct.React.createElement('div', null, MyComponent)is incorrect ifMyComponentis a component. - Why it works:
React.createElementexpects a valid "type" for the first argument, which can be a string (like'div') or a component constructor function.
6. Using children Prop Incorrectly
- Diagnosis: When passing children to a component that expects them, you might be passing a function directly as a child.
- Cause:
props.childrencan be anything, including a function. If you then try to renderprops.childrendirectly without calling it, you’ll get this error. - Fix: If
props.childrenis a function you intend to call, do so:{props.children()}. If it’s not meant to be a function, ensure you’re passing valid JSX or primitive types as children. - Why it works: You’re explicitly invoking the function when it’s passed as a child, so React receives its return value.
After fixing this, you might encounter Objects are not valid as a React child if you accidentally try to render a plain JavaScript object.