useState() hook to create a state variable, containing content and wordCount. Use the value prop and 0 as the initial values respectively.useCallback() hooks to create a memoized function, setFormattedContent, that uses String.prototype.split() to turn the input into an array of words.Array.prototype.filter() combined with Boolean has a length longer than limit. If it does, trim the input. Otherwise return the raw input, updating state accordingly in both cases.useEffect() hook to call the setFormattedContent method on the value of the content state variable during the initial render.onChange event of the <textarea> to call setFormattedContent with the value of event.target.value.const LimitedWordTextarea = ({ rows, cols, value, limit }) => {
const [{ content, wordCount }, setContent] = React.useState({
content: value,
wordCount: 0
});
const setFormattedContent = React.useCallback(
text => {
let words = text.split(' ').filter(Boolean);
if (words.length > limit) {
setContent({
content: words.slice(0, limit).join(' '),
wordCount: limit
});
} else {
setContent({ content: text, wordCount: words.length });
}
},
[limit, setContent]
);
React.useEffect(() => {
setFormattedContent(content);
}, []);
return (
<>
<textarea
rows={rows}
cols={cols}
onChange={event => setFormattedContent(event.target.value)}
value={content}
/>
<p>
{wordCount}/{limit}
</p>
</>
);
};
ReactDOM.render( <LimitedWordTextarea limit={5} value="Hello there!" />, document.getElementById('root') );
Subscribe to get resources directly to your inbox. You won't receive any spam! ✌️