I’m implementing a "characters left" feature for a textarea. When the user types it should countdown to zero and then stop the user entry. I’m using a useRef to bind to the textarea and output it’s length value in the paragraph but it’s not working although cntCharLeft.current.value.length is printing out correctly in the onChange method in textarea. Error message: Uncaught TypeError: Cannot read properties of undefined (reading 'length')
How do I print out the length of the ref in the paragraph to display the number of characters left and then stop the user input once the maximum (250) characters has been reached?
const cntCharLeft=useRef(0);
const submitHandler=(e)=>{
......
}
return(
<Card className={styles.content} >
<form onSubmit={submitHandler}>
<textarea rows='6' ref={cntCharLeft} onChange={e=>{
console.log(cntCharLeft.current.value.length)
}} />
<p className={styles.charsLeft} >{250-cntCharLeft.current.value.length} characters left</p>
<Button type='submit'>Enter</Button>
</form>
</Card>
)
>Solution :
You can use the maxlength attribute on the <textarea> HTML element to restrict the number of characters.
Also you should consider to use useState() to store the value within the textarea. By doing so the component re-renders and the character count updates. Also by using onInput instead of onChange you ensure that the state is updated on every keystroke.
function Textarea({ maxLength }){
const [value, setValue] = React.useState("");
function handleInput(e){
const newValue = e.target.value;
if(newValue.length <= maxLength){
setValue(newValue);
}
}
function submitHandler(){
console.log("Submitted form");
}
return(
<form onSubmit={submitHandler}>
<textarea rows='6' onInput={handleInput} maxlength={maxLength} />
<p>{maxLength - value.length} characters left</p>
<button type='submit'>Enter</button>
</form>
);
}
ReactDOM.render(<Textarea maxLength={25} />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id="root"></div>