Understanding innerText in Javascript
If you’re working with contentEditable elements in React and using hooks like useRef(), you might encounter a puzzling situation: innerText logs correctly in the console but doesn’t appear in alerts. Let’s dive into the possible reasons and solutions for this behavior, with a focus on debugging effectively.
Problem Overview
Code Example
Here’s a common implementation that might cause issues:
import React, { useRef } from 'react';
export default function Input() {
const inputRef = useRef();
const showText = () => {
console.log("text: ", inputRef.current.innerText);
alert("text: ", inputRef.current.innerText);
};
return (
<>
<div ref={inputRef} contentEditable="true" suppressContentEditableWarning={true} />
<button onClick={showText}>Show text</button>
</>
);
}
How to fix
There are several solutions to this issue:
- Use Template Literals:
const showText = () => {
alert(`text: ${inputRef.current.innerText}`);
};
- Use textContent Instead:
const showText = () => {
alert("text: " + inputRef.current.textContent);
};
- Add State Management:
**const [text, setText] = useState('');
const showText = () => {
const currentText = inputRef.current.innerText;
setText(currentText);
alert("text: " + currentText);
};**
Why It Happens
The issue often occurs because:
- Alert concatenation might not properly convert the innerText to a string
- The reference might not be fully updated when the alert is called
- React’s synthetic events and state updates can interfere with direct DOM manipulation
Best Practices
Always verify that your ref is properly initializedConsider using controlled components instead of refs when possibleUse state management for better predictabilityAdd error handling for cases where the ref might be null