The createRef function is being called as a regular function instead of being accessed as a property of the React object.

Here are the common causes and how to fix them:

  1. Incorrect Import: You might be importing createRef directly without importing React itself, or you’re importing it from the wrong place.

    • Diagnosis: Look at your import statements. Do you have import { createRef } from 'react'; without import React from 'react'; or import * as React from 'react';? Or is it possible you’re importing from a different library?
    • Fix: Ensure you have import React from 'react'; or import * as React from 'react'; and then use React.createRef().
      import React from 'react'; // or import * as React from 'react';
      
      class MyComponent extends React.Component {
        constructor(props) {
          super(props);
          this.myRef = React.createRef(); // Correct usage
        }
        // ...
      }
      
    • Why it works: createRef is a method on the main React object, not a standalone export in most common React versions. Importing React and accessing it as React.createRef ensures you’re using the correct, globally available function within the React library.
  2. Using createRef with Older React Versions: If you are on a very old version of React (prior to 16.3), createRef might not be available or might be imported differently.

    • Diagnosis: Check your package.json for the react version. If it’s below 16.3, this is likely the issue.
    • Fix: For older versions, you would typically use React.PropTypes.object.isRequired or a string ref (though string refs are deprecated). If you can, upgrade React to 16.3 or later.
      // For React < 16.3, consider upgrading. If not possible:
      // String refs are deprecated and not recommended.
      // For functional components, you'd use hooks like useRef.
      // For class components, you might need to rethink the approach or upgrade.
      
    • Why it works: Newer React versions introduced createRef as a stable API. Older versions relied on different patterns. Upgrading ensures compatibility with the modern API.
  3. Typos in Variable/Function Names: A simple typo when defining or calling createRef can cause this.

    • Diagnosis: Carefully examine the line where you are calling createRef. Is it spelled exactly createRef? Are there any stray characters?
    • Fix: Correct any spelling mistakes.
      // Incorrect:
      // this.myRef = createRef(); // If React is not imported as 'React' or createRef not imported directly.
      
      // Correct (assuming React is imported as 'React'):
      this.myRef = React.createRef();
      
    • Why it works: Programming languages are case-sensitive and require exact names for functions and variables. Correcting the typo ensures the interpreter can find and execute the intended function.
  4. Conflicting Variable Name: You might have declared a local variable or function named createRef that shadows the imported React.createRef.

    • Diagnosis: Search your component’s code for any other declarations of createRef.
    • Fix: Rename your local createRef variable or function to something unique.
      // Inside your component:
      // const createRef = 'some value'; // This would shadow React.createRef
      
      // Fix:
      // const myLocalRefVariable = 'some value';
      // this.myRef = React.createRef(); // Still correct
      
    • Why it works: When you call createRef(), JavaScript looks for a createRef in the current scope. If it finds a local one first, it uses that, which is likely not the intended React function. Renaming the local variable ensures React.createRef is found.
  5. Incorrect Scope for createRef Usage: In some more complex scenarios, especially with nested components or hocs, the React object might not be accessible in the scope where createRef is being called.

    • Diagnosis: Trace the execution flow. Is the createRef call happening within a context where React is guaranteed to be available?
    • Fix: Ensure that import React from 'react'; is present and that the React object is accessible in the scope. If using module bundlers, verify that the React import is correctly processed.
      // Ensure this import is at the top of the file:
      import React from 'react';
      
      class MyComponent extends React.Component {
        constructor(props) {
          super(props);
          // React is available here
          this.myRef = React.createRef();
        }
        // ...
      }
      
    • Why it works: React.createRef requires the React object to be in scope. If the import is missing or the React object is somehow undefined in that specific part of the code, the call will fail.
  6. Using createRef in a Functional Component without useRef: While createRef is primarily for class components, you might mistakenly try to use it in a functional component.

    • Diagnosis: Check if you are in a functional component and using createRef.
    • Fix: Use the useRef hook in functional components.
      import React, { useRef } from 'react';
      
      function MyFunctionalComponent() {
        const myRef = useRef(null); // Correct usage for functional components
      
        return <div ref={myRef}>Hello</div>;
      }
      
    • Why it works: useRef is the hook equivalent of createRef for functional components, providing a mutable ref object that persists across renders.

After fixing any of these issues, you might encounter a "Cannot read properties of undefined (reading 'current')" error if you try to access myRef.current before the component has mounted or if the element the ref is attached to doesn’t exist.

Want structured learning?

Take the full React course →