英文:
Text area characters left (countdown) with a useRef hook
问题
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 its length value in the paragraph, but it's not working although cntCharLeft.current.value.length
is printing out correctly in the onChange method in the 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 have been reached?
const cntCharLeft = useRef(""); // Change 0 to an empty string
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>
);
不要回答我要翻译的问题。
英文:
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>
)
答案1
得分: 2
请注意,当您使用useRef
时,文本区域的更改不会强制重新渲染。考虑将文本区域设置为受控输入,将目标值放入状态中,或者在onChange
调用时将输入的长度放入状态中。这两个选项都消除了对引用的依赖,并在文本区域值更改时强制组件重新渲染。
英文:
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 to onChange
, 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.
答案2
得分: 1
你可以使用 maxlength
属性在 <textarea>
HTML 元素上限制字符数。
还应考虑使用 useState()
来存储文本区域内的值。这样做可以使组件重新渲染并更新字符计数。此外,通过使用 onInput
而不是 onChange
,可以确保每次按键时状态都会更新。
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>
英文:
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.
<!-- begin snippet: js hide: false console: true babel: true -->
<!-- language: lang-js -->
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'));
<!-- language: lang-html -->
<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>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论