How to fix Warning: String "ref" is deprecated and will be removed in React

ReactBEGINNERMEDIUMUpdated Dec 10, 2025· 159 views

React is warning that string-based refs (e.g., ref="myInput") are deprecated. String refs have multiple downsides including poor composability, debugging issues, and will be removed in React 19. You need to migrate to useRef, createRef, or callback refs.

Quick fix

Fixes Warning: String "ref" is deprecated and will be removed

# Search for string refs in your codebase
grep -r 'ref="' src/
grep -r "ref='" src/
grep -r 'this.refs' src/
  1. Identify all string refs in your codebase
  2. Migrate function components to useRef hook
  3. Migrate class components to createRef
  4. Use callback refs for dynamic or conditional refs
react — error
# Search for string refs in your codebase
grep -r 'ref="' src/
grep -r "ref='" src/
grep -r 'this.refs' src/
Warning: String "ref" is deprecated and will be removed

What this error means

This warning appears when you're using the legacy string ref syntax in React components. String refs were the original way to reference DOM elements or component instances in React, but they've been deprecated since React 16.3 (March 2018) and are being completely removed in React 19. String refs look like this: `<input ref="myInput" />` and are accessed via `this.refs.myInput`. While they seem simple, they have several fundamental problems: - **Not composable**: If a wrapper component also uses a string ref with the same name, they overwrite each other - **Poor debugging**: Errors are harder to trace when refs collide - **No TypeScript support**: String refs don't work well with static type checking - **Framework complexity**: They require React to maintain a special refs object on every component instance React's core team deprecated string refs in favor of callback refs, createRef, and the useRef hook, which provide better type safety, composability, and debugging capabilities.

Typical symptoms

  • Warning message in browser console: "String ref is deprecated"
  • ESLint warning: "Using string literals in ref attributes is deprecated (react/no-string-refs)"
  • Build warnings when upgrading to React 18.3 or preparing for React 19
  • Application works normally but shows deprecation warnings in development
  • Warning appears for each component using string refs

Common causes

  1. Using legacy string ref syntax like ref="myRef" in class or function components
  2. Accessing refs via this.refs.myRef in class components
  3. Old codebase that hasn't been updated since before React 16.3
  4. Following outdated tutorials or documentation that predate 2018
  5. Third-party libraries still using string refs internally

How to fix "Warning: String "ref" is deprecated and will be removed"

1Identify all string refs in your codebase

Search your project for string ref usage:

bash
# Search for string refs in your codebase
grep -r 'ref="' src/
grep -r "ref='" src/
grep -r 'this.refs' src/

Common patterns to look for:
- ref="inputRef"
- this.refs.inputRef
- this.refs['inputRef']

2Migrate function components to useRef hook

For function components, replace string refs with the useRef hook:

Before (string ref - deprecated):

jsx
function MyComponent() {
  const handleClick = () => {
    // This won't work with function components
    this.refs.inputRef.focus();
  };

  return <input ref="inputRef" />;
}

After (useRef hook - recommended):

jsx
import { useRef } from 'react';

function MyComponent() {
  const inputRef = useRef(null);

  const handleClick = () => {
    inputRef.current?.focus();
  };

  return <input ref={inputRef} />;
}

The useRef hook creates a mutable ref object with a .current property that persists across re-renders.

3Migrate class components to createRef

For class components, use React.createRef() in the constructor:

Before (string ref - deprecated):

jsx
class MyComponent extends React.Component {
  handleClick = () => {
    this.refs.inputRef.focus();
  }

  render() {
    return <input ref="inputRef" />;
  }
}

After (createRef - recommended):

jsx
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  handleClick = () => {
    this.inputRef.current?.focus();
  }

  render() {
    return <input ref={this.inputRef} />;
  }
}

Create the ref in the constructor and access it via .current.

4Use callback refs for dynamic or conditional refs

For more control over when refs are set or unset, use callback refs:

jsx
function MyComponent() {
  const [inputElement, setInputElement] = React.useState(null);

  const handleRef = (element) => {
    setInputElement(element);
    // You can perform actions when the ref is set
    if (element) {
      console.log('Input mounted:', element);
    }
  };

  return <input ref={handleRef} />;
}

Or in class components:

jsx
class MyComponent extends React.Component {
  inputRef = null;

  setRef = (element) => {
    this.inputRef = element;
  }

  render() {
    return <input ref={this.setRef} />;
  }
}

Callback refs are useful when you need to perform side effects when a ref is attached or detached.

5Update third-party library dependencies

If the warning comes from a third-party library, check for updates:

bash
# Check for outdated packages
npm outdated

# Update specific package
npm update package-name

# Or update to latest version
npm install package-name@latest

If the library hasn't been updated:
- Check the library's GitHub issues for migration plans
- Consider switching to an actively maintained alternative
- File an issue requesting React 19 compatibility
- Fork and patch if necessary (last resort)

6Test thoroughly after migration

After migrating refs, test all affected functionality:

jsx
// Example test with React Testing Library
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('input ref works correctly', () => {
  render(<MyComponent />);
  const input = screen.getByRole('textbox');

  // Verify ref-based operations work
  expect(document.activeElement).not.toBe(input);
  userEvent.click(screen.getByText('Focus Input'));
  expect(document.activeElement).toBe(input);
});

Test scenarios:
- Focus management
- Scroll positioning
- DOM measurements
- Third-party library integrations
- Animation triggers

Advanced notes

## When to use each ref approach

useRef (function components):
- Default choice for function components
- Simple DOM access
- Storing mutable values without triggering re-renders
- Persists across re-renders

createRef (class components):
- Standard approach for class components
- Created in constructor
- Attached to instance properties

Callback refs:
- When you need notification when ref attaches/detaches
- Dynamic refs (refs in lists or conditional rendering)
- Synchronizing refs with state
- Measuring DOM nodes immediately after mounting
- Integrating with non-React code

## React 19 changes

React 19 completely removes string refs. If you're upgrading:

1. Upgrade to React 18.3 first - it adds warnings for all deprecated APIs
2. Fix all string ref warnings
3. Update dependencies to React 19-compatible versions
4. Then upgrade to React 19

React 19 also introduces ref as a prop on function components, eliminating the need for forwardRef in many cases:

jsx
// React 19+
function MyInput({ ref }) {
  return <input ref={ref} />;
}

## Performance considerations

Avoid inline callback refs in hot render paths:

jsx
// ❌ Avoid: Creates new function every render
<input ref={(el) => this.inputRef = el} />

// ✅ Better: Stable function reference
<input ref={this.setInputRef} />

Inline callback refs are called twice during updates (first with null, then with the element), which can cause unnecessary work.

## TypeScript support

Modern refs have excellent TypeScript support:

tsx
import { useRef } from 'react';

function MyComponent() {
  // Type is inferred from initial value
  const inputRef = useRef<HTMLInputElement>(null);

  const focusInput = () => {
    // TypeScript knows inputRef.current might be null
    inputRef.current?.focus();
  };

  return <input ref={inputRef} />;
}

String refs have no TypeScript support, making them unsuitable for typed codebases.

Frequently asked questions

What does "Warning: String "ref" is deprecated and will be removed" mean?
This warning appears when you're using the legacy string ref syntax in React components. 3 (March 2018) and are being completely removed in React 19. myInput.
How do I fix "Warning: String "ref" is deprecated and will be removed"?
React is warning that string-based refs (e.g., ref="myInput") are deprecated. String refs have multiple downsides including poor composability, debugging issues, and will be removed in React 19. You need to migrate to useRef, createRef, or callback refs.
What causes "Warning: String "ref" is deprecated and will be removed"?
Using legacy string ref syntax like ref="myRef" in class or function components Accessing refs via this.refs.myRef in class components Old codebase that hasn't been updated since before React 16.3
Is the "Warning: String "ref" is deprecated and will be removed" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading