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>
)
2
Answers
While you’re using
useRef
, note that the change in the text area is not forcing a re-render. Consider making the text area a controlled input, placing the target value in state — either that, or on calls toonChange
, place the length of the input in state. Both of these options remove the dependence on refs, and force component re-renders on text area value changes.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 usingonInput
instead ofonChange
you ensure that the state is updated on every keystroke.