Why are String Refs legacy?
Assesses fundamental understanding of React conventions, runtime behavior, and memory/performance considerations.
Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.
If you worked with React before, you might be familiar with an older API where the ref attribute is a string, like ref={'textInput'}, and the DOM node is accessed as this.refs.textInput. We advise against it because _string refs have below issues_, and are considered legacy. String refs were removed in React v16.
- They _force React to keep track of currently executing component_. This is problematic because it makes react module stateful, and thus causes weird errors when react module is duplicated in the bundle.
- They are _not composable_ — if a library puts a ref on the passed child, the user can't put another ref on it. Callback refs are perfectly composable.
- They _don't work with static analysis_ like Flow. Flow can't guess the magic that framework does to make the string ref appear on
this.refs, as well as its type (which could be different). Callback refs are friendlier to static analysis. - It doesn't work as most people would expect with the "render callback" pattern (e.g. <DataGrid renderRow={this.renderRow} />)
```jsx harmony
class MyComponent extends Component {
renderRow = (index) => {
// This won't work. Ref will get attached to DataTable rather than MyComponent:
return <input ref={"input-" + index} />;
// This would work though! Callback refs are awesome.
return <input ref={(input) => (this["input-" + index] = input)} />;
};
render() {
return (
<DataTable data={this.props.data} renderRow={this.renderRow} />
);
}
}
```
> Modern React Note: String refs are deprecated. Use the useRef() Hook in function components or React.createRef() in class components.
Candidate Response Strategy & Interview Tips
- Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
- Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
- Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
- Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.