React 30 秒速学:制作多行文本组件,限制字符数和单词数

本文同时发布于掘金,地址:https://juejin.im/post/6844903846926352397

本文译自:30-seconds-of-react。React 30 秒速学:全篇中文翻译、学习,地址:30-seconds-of-react-zh_CN-umi,所有案例进行分析、注释、上线。

TextArea多行文本

呈现一个<textarea>元素,该元素使用回调函数将其值传递给父组件。

  • 使用对象解构来设置<textarea>元素的某些属性的默认值。
  • 使用适当的属性渲染<textarea>元素,并使用onChange事件中的callback函数将textarea的值传递给父元素。
function TextArea({
  callback,
  cols = 20,
  rows = 2,
  disabled = false,
  readOnly = false,
  placeholder = ''
}) {
  return (
    <textarea
      cols={cols}
      rows={rows}
      disabled={disabled}
      readOnly={readOnly}
      placeholder={placeholder}
      onChange={({ target: { value } }) => callback(value)}
    />
  );
}

例子

export default function() {
  return (
    <TextArea
      placeholder="Insert some text here..."
      callback={val => console.log(val)}
    />
  );
}

ps:

LimitedTextarea限制字符数的多行文本

呈现限制字符数的多行文本组件。

  • 使用React.useState() hook 创建content状态变量并将其值设置为value
    创建一个方法setFormattedContent,如果它比limit长,它会修剪输入的内容。
  • 使用React.useEffect() hook 来调用content状态变量值的setFormattedContent方法。
  • 使用<div>来包装<textarea><p>元素,它显示字符数并绑定<textarea>onChange事件来调用setFormattedContent处理 event.target.value的值。

参考: hook文档

import React from "react";
function LimitedTextarea({ rows, cols, value, limit }) {
  // React.useState(初始值) 通过在函数组件里调用它,来给组件添加一些内部 state
  // 返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。
  const [content, setContent] = React.useState(value);

  const setFormattedContent = text => {
    console.log("setFormattedContent");
    // 符合长度才允许修改
    text.length > limit ? setContent(text.slice(0, limit)) : setContent(text);
  };

  // useEffect 就是一个 Effect Hook ,在组件挂载和更新时执行
  // 可以看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个生命周期函数的组合
  React.useEffect(() => {
    console.log("useEffect");
    setFormattedContent(content);
  }, []);

  return (
    <div>
      <textarea
        rows={rows}
        cols={cols}
        onChange={event => setFormattedContent(event.target.value)}
        value={content}
      />
      <p>
        {content.length}/{limit}
      </p>
    </div>
  );
}

例子

export default function() {
  return <LimitedTextarea limit={32} value="Hello!" />;
}

ps:

LimitedWordTextarea 限制单词数的多行文本

呈现限制单词数的多行文本组件。

  • 使用React.useState() hook 创建contentwordCount状态变量,并将它们的值分别设置为value0
  • 创建一个方法setFormattedContent,它使用String.prototype.split(' ')将输入转换为单词数组,并使用 Array.prototype.filter(Boolean)检查 length是否比 limit长。
  • 如果上述length超过limit,则修剪输入,否则返回原始输入,在两种情况下都相应地更新contentwordCount
  • 使用React.useEffect() hook 来调用content状态变量值的setFormattedContent方法。
  • 使用<div>来包装<textarea><p>元素,它显示字符数并绑定<textarea>onChange事件来调用setFormattedContent 处理 event.target.value的值。
function LimitedWordTextarea({ rows, cols, value, limit }) {
  const [content, setContent] = React.useState(value);
  const [wordCount, setWordCount] = React.useState(0);

  const setFormattedContent = text => {
    let words = text.split(" ");
    // words.filter(Boolean).length 获取数组长度
    // .filter(Boolean) 等价于 .filter((item) => {return Boolean(item)})
    // 也就是说这样写的意思就是去除数组中为 “假” 的元素
    if (words.filter(Boolean).length > limit) {
      setContent(
        text
          .split(" ")
          .slice(0, limit)
          .join(" ")
      );
      setWordCount(limit);
    } else {
      setContent(text);
      setWordCount(words.filter(Boolean).length);
    }
  };

  React.useEffect(() => {
    setFormattedContent(content);
  }, []);

  return (
    <div>
      <textarea
        rows={rows}
        cols={cols}
        onChange={event => setFormattedContent(event.target.value)}
        value={content}
      />
      <p>
        {wordCount}/{limit}
      </p>
    </div>
  );
}

例子

export default function() {
  return <LimitedWordTextarea limit={5} value="Hello there!" />;
}

ps:

本文收录于专栏
译自:30-seconds-of-react 项目,全篇中文翻译、学习,所有案例进行分析、注释、上线。