带有字数限制的文本区域

渲染一个带有字数限制的文本区域组件。

  • 使用 useState() 钩子创建一个包含 contentwordCount 的状态变量,分别将 value 属性和 0 作为初始值。
  • 使用 useCallback() 钩子创建一个记忆化函数 setFormattedContent,它使用 String.prototype.split() 将输入转换为一个单词数组。
  • 检查应用 Array.prototype.filter() 结合 Boolean 的结果是否比 limit 更长。如果是,则修剪输入。否则返回原始输入,并在两种情况下更新状态。
  • 使用 useEffect() 钩子在初始渲染时调用 setFormattedContent 方法,并传入 content 状态变量的值。
  • <textarea>onChange 事件绑定到调用 setFormattedContent 并传入 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.createRoot(document.getElementById('root')).render(
  <LimitedWordTextarea limit={5} value="Hello there!" />
);