使用 @mention 功能构建 React 评论表单

@mention在引入功能之前,对线程和消息的评论曾经非常混乱。尽管您可以在线程中发送消息,但通常无法知道该消息是针对谁的,并且无法吸引那些尚未参与对话的人。

通过 的介绍@mention,您可以提及朋友(或善意的社交媒体专家)并邀请他们加入讨论。

您还可以@mention在 Facebook、Dropbox、WhatsApp 和 Gmail 等各种应用程序中找到具有功能的表单。

本文将着眼于构建一个具有@mentionReact 中包含的功能的表单。我们将专门使用该react-mentions软件包。

您可以在我的 Github 存储库中找到本教程的完整代码。让我们开始吧!

  • 建立一个评论表单react-mentions

  • 使用MentionsInput和Mention组件

  • 样式react-mentions组件

  • 探索其他功能react-mentions

    • singleLine输入

    • 多种触发模式

    • 修改显示id

    • 可滚动的文本区域

    • 从外部来源获取响应

    • 获取表情符号

  • 创建具有@mention功能的自定义表单

建立一个评论表单react-mentions

让我们首先使用以下命令创建一个新的 React 应用程序:

npx create-react-app react-mentions

如果您使用的是 Yarn,请运行以下命令:

yarn create react-app react-mentions

我将在本教程的其余部分使用 Yarn。

接下来,安装react-mentions包如下:

yarn add react-mentions

该react-mentions包导出两个 React 组件用于渲染提及:MentionsInput组件和Mention组件。MentionsInput是用于渲染文本区域控件的主要组件,可以将一个或多个Mention组件作为子组件。

该Mention组件表示一类可提及对象的数据源,包括用户、问题等。

使用MentionsInput和Mention组件

让我们react-mentions在我们的应用程序中实现。转到App.js文件并用下面的代码块替换整个代码:

import { Mention, MentionsInput } from "react-mentions";
​
function App() {
  return (
    
     

Let's get started

                       
); } export default App;

当我们用 启动开发服务器时yarn start,我们应该得到一个如下图所示的输入框:

接下来,我们将创建一个提供给Mention组件的虚拟数据数组。数据必须具有id和display作为特定键。

我们还需要创建一个状态事件。这将用于将我们的应用程序的状态绑定到来自数据的值,然后将其传递给MentionsInput组件。

将以下代码复制并粘贴到App.js文件中:

function App() {
  const [value, setValue] = useState("");
​
  const users = [
    {
      id: "isaac",
      display: "Isaac Newton",
    },
    {
      id: "sam",
      display: "Sam Victor",
    },
    {
      id: "emma",
      display: "[email protected]",
    },
  ];
​
  ...
}

我们根据上面的代码块创建了一个状态变量和用户数组。用户数组包含带有id和display参数的对象。react-mentions这些是填充组件所需的参数。

现在,让我们return()用下面的代码更新语句:

  return (
    
      setValue(e.target.value)}> ​                  
);

我们正在使用接受道具的MentionsInput标签。value然后我们使用onChange道具设置状态值。完成所有这些后,我们应该能够实现这一点:

样式react-mentions组件

看看我们上面的进度,你可能会注意到我们的组件看起来有点不合适。我们可以通过自定义样式来修复它。

在文件夹中创建一个mentionStyles.js文件src并粘贴以下代码:

export default {
  backgroundColor: "#cee4e5",
};

在文件夹中创建一个mentionsInputStyles.js文件src并将下面的代码块粘贴到其中:

export default {
  control: {
    backgroundColor: '#fff',
    fontSize: 16,
    // fontWeight: 'normal',
  },
  '&multiLine': {
    control: {
      fontFamily: 'monospace',
      minHeight: 63,
    },
    highlighter: {
      padding: 9,
      border: '1px solid transparent',
    },
    input: {
      padding: 9,
      border: '1px solid silver',
    },
  },
  '&singleLine': {
    display: 'inline-block',
    width: 180,
    highlighter: {
      padding: 1,
      border: '2px inset transparent',
    },
    input: {
      padding: 1,
      border: '2px inset',
    },
  },
  suggestions: {
    list: {
      backgroundColor: 'white',
      border: '1px solid rgba(0,0,0,0.15)',
      fontSize: 16,
    },
    item: {
      padding: '5px 15px',
      borderBottom: '1px solid rgba(0,0,0,0.15)',
      '&focused': {
        backgroundColor: '#cee4e5',
      },
    },
  },
}

返回App.js并导入样式:

import mentionStyle from "./mentionStyle";
import mentionsInputStyle from "./mentionsInputStyle";

现在,更新组件:

    
setValue(e.target.value)}>

我们通过添加 style 属性并将其设置为导入的样式来更新我们的组件。

到目前为止,随着我们的进步,我们已经Mention在我们的应用程序中实现了一个很好的定制功能!


超过 20 万开发人员使用 LogRocket 来创造更好的数字体验了解更多 →


探索其他功能react-mentions

该react-mentions软件包带有许多可定制的功能,所以让我们来看看其中的一些!

singleLine输入

singleLine当我们希望我们的输入是单行文本而不是默认文本区域时,会调用 input。您可以在下面的代码中看到这一点:

return (
 
...

Using a Single line Input

setValue(e.target.value)} >
);

多种触发模式

我们还可以决定使用多个触发模式而不是默认@触发模式。幸运的是,该react-mention软件包支持这一点。

让我们启动第二个触发模式。在文件中导入useCallback钩子。App.js该useCallback钩子用于阻止Mention组件在不需要的情况下重新渲染:

import { useState, useCallback } from "react";

接下来,创建一个电子邮件验证正则表达式。这将作为一个额外的触发器来检测输入是否是电子邮件。然后它将突出显示它作为提及。

function App() {
  const [value, setValue] = useState("");
  const emailRegex = /(([^\s@]+@[^\s@]+\.[^\s@]+))$/;

  ...
  return (
    

Using Multiple trigger patterns

setValue(e.target.value)} > [{ id: search, display: search }]} onAdd={useCallback((...args) => { console.log(...args); }, [])} style={{ backgroundColor: "#d1c4e9" }} />
);

修改显示id

该react-mentions库还允许我们将默认显示更改id为我们喜欢的显示。我们可以通过使用displayTransform参数来实现这一点。

   

Displaying ID

setValue(e.target.value)} > ``} style={mentionStyle} data={users} />

在上面的代码块中,我们id从用户对象返回并渲染它。

可滚动的文本区域

文本区域是响应式输入字段,可根据多个用户输入调整高度。此功能可能会导致 UI 失真并适用于我们的react-mentions组件。我们将让我们的文本区域可滚动以避免这种扭曲,并创建一个更好的 UI。

首先,我们将merge函数从lodash库中导入到App.js文件中:

import merge from 'lodash/merge';

该merge函数将负责将我们mentionsInputStyle的样式与我们的新自定义样式合并。


来自 LogRocket 的更多精彩文章:

  • 不要错过来自 LogRocket 的精选时事通讯The Replay

  • 了解LogRocket 的 Galileo 如何消除噪音以主动解决应用程序中的问题

  • 使用 React 的 useEffect优化应用程序的性能

  • 在多个 Node 版本之间切换

  • 了解如何使用 AnimXYZ 为您的 React 应用程序制作动画

  • 探索 Tauri,一个用于构建二进制文件的新框架

  • 比较NestJS 与 Express.js


function App() {
  let customStyle = merge({}, mentionsInputStyle, {
    input: {
      height: 80,
      overflow: "auto",
    },
    highlighter: {
      height: 80,
      overflow: "hidden",
      boxSizing: "border-box",
    },
  });

  ...
  return (
       setValue(e.target.value)}
        style={customStyle}
        placeholder={"Mention people using '@'"}
        a11ySuggestionsListLabel={"Suggested mentions"}
      >
        
  );
}

在上面的代码块中,我们将 合并mentionsInputStyle到我们新更新的样式中。我们还将文本区域的高度和宽度设置为固定值并自动设置溢出。

完成后,我们将拥有一个更好的带有可滚动组件的 UI,如下所示:

从外部来源获取响应

在本节中,我们将了解如何在表单中使用来自 API 的数据。在许多情况下,我们的数据可能来自外部来源。让我们看看我们如何处理我们的响应并将它们添加到react-mentionsdata 属性中。

我们将为此演示使用JSON 占位符 API并从中获取用户。将下面的代码块复制并粘贴到App.js文件中:

  function fetchUsers(query, callback) {
    if (!query) return;
    fetch(`https://jsonplaceholder.typicode.com/users?q=${query}`, {
      json: true,
    })
      .then((res) => res.json())
      // Transform the users to what react-mentions expects
      .then((res) => 
        res.map((user) => ({ display: user.username, id: user.name }))
      )

      .then(callback);
  }

根据上面的代码块,我们正在对jsonplaceholder服务器进行 API 调用。我们将两个参数传递给fetch函数:query和callback。

该query参数保存来自 的输入mentionInput,而callback当我们准备好响应时调用该参数。

接下来,我们返回一个用户列表,循环遍历它,并将用户名和用户名作为 and 的对象display返回id。

最后,我们在MentionsInput组件的 data 属性中调用我们的函数并显示id:

    setValue(e.target.value)}
        style={mentionsInputStyle}
        placeholder="Mention any JsonPlaceholder username by typing `@` followed by at least one character"
        a11ySuggestionsListLabel={"Suggested JsonPlaceholder username for mention"}
      >
         `@${id}`}
          trigger="@"
          data={fetchUsers}
          style={mentionStyle}
        />
      

获取表情符号

有了这个react-mentions包,不仅可以引用和提及名字,还可以提及表情符号!

让我们看看如何从外部 API 获取表情符号,并在搜索时将它们显示在输入字段中。

function App() {
  const [emojiValue, setEmojiValue] = useState([]);
  const notMatchingRegex = /($a)/;

  useEffect(() => {
    fetch(
      "https://gist.githubusercontent.com/oliveratgithub/0bf11a9aff0d6da7b46f1490f86a71eb/raw/d8e4b78cfe66862cf3809443c1dba017f37b61db/emojis.json"
    )
      .then((data) => {
        return data.json();
      })
      .then((jsonData) => {
        setEmojiValue(jsonData.emojis);
      });
  }, []);
  const queryEmojis = (query, callback) => {
    if (query.length === 0) return;
    const filterValue = emojiValue
      .filter((emoji) => {
        return emoji.name.indexOf(query.toLowerCase()) > -1;
      })
      .slice(0, 10);
    return filterValue.map(({ emoji }) => ({ id: emoji }));
  };

  ...
  return (
      

Emoji support

setValue(e.target.value)} style={mentionsInputStyle} placeholder={"Press '&' for emojis, mention people using '@'"} > `@${username}`} markup="@__id__" data={users} regex={/@(\S+)/} style={mentionStyle} appendSpaceOnAdd /> ); }

emojiValue根据上面的代码块,我们会在页面加载后立即从我们的 API 中获取并存储表情符号。我们使用useEffect钩子执行此操作,并在用户搜索特定关键字时显示表情符号。

在这里,我们使用双触发模式,使用&emojis 符号和@users 数组符号。notMatchingRegex用作不匹配表情符号的过滤器。

创建具有@mention功能的自定义表单

在本节中,我们将把我们所了解的关于react-mentions库的所有内容放在一起来构建一个评论表单。

首先,在目录中创建一个CustomForm.jsx文件src并粘贴以下代码:

// CustomForm.jsx

import { useState } from 'react';
import { Mention, MentionsInput } from 'react-mentions';
import styles from './FormInputStyle.module.css';
import mentionsInputStyle from './mentionsInputStyle';
import mentionStyle from './mentionStyle';
const CustomForm = () => {
  const [formState, setFormState] = useState({
    username: '',
    comment: '',
  });
  const [comments, setComments] = useState([]);
  const users = [
    {
      id: 'isaac',
      display: 'Isaac Newton',
    },
    {
      id: 'sam',
      display: 'Sam Victor',
    },
    {
      id: 'emma',
      display: '[email protected]',
    },
  ];
  const submit = () => {
    if (formState.username === '' || formState.comment === '') {
      alert('Please fill in all fields');
      return;
    }
    setComments((comments) => [
      ...comments,
      {
        username: formState.username,
        comment: formState.comment,
      },
    ]);
    setFormState({
      username: '',
      comment: '',
    });
  };
  const current = new Date();
  const date = `${current.getDate()}/${
    current.getMonth() + 1
  }/${current.getFullYear()}`;

在上面的代码中,我们导入了我们将要使用的包react-mentions以及useState用于处理表单的注释和状态的钩子。

表单和评论状态也已设置并为应用程序提供虚拟数据。影音壳子App,TVbox最新魔改版双播神器,内置80+数据源接口覆盖全网!我们的submit函数检查字段是否已填写并设置评论状态。我们现在有一个date获取评论日期的变量。

现在,使用以下代码更新返回值:

return (
    

Comment Form

setFormState({ ...formState, username: e.target.value }) } placeholder="Input Your Name" /> setFormState({ ...formState, comment: e.target.value }) } style={mentionsInputStyle} >
{comments.length === 0 ? ( null ) : (
{comments.map((comment, i) => (

{comment.username} on {date}

{comment.comment}

))}
)}
); }; export default CustomForm;

我们将适当的道具传递给Mention和MentionInput组件,并在表单下方显示评论(如果有的话)。

伟大的!接下来,创建一个FormInputStyle.module.cssfor 样式并将以下代码粘贴到其中:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.form {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100vh;
  background-color: #ffa5a5;
}
.formTitle {
  font-size: 2rem;
  color: red;
  margin-bottom: 1rem;
}
input {
  height: 3rem;
  width: 25rem;
  margin-bottom: 1rem;
  padding: 1rem;
  font-size: 18px;
  border: 1px solid silver;
}
.formCard {
  width: 27rem;
  display: flex;
  flex-direction: column;
  background-color: rgb(54, 44, 24);
  padding: 1rem;
}
button {
  border: none;
  border-radius: 3px;
  color: white;
  background-color: green;
  font-size: 1.2rem;
  padding: 10px;
  margin-top: 1rem;
}
.commentCard {
  margin: 1.5rem;
  color: rgb(173, 173, 173);
  font-size: 1rem;
  background-color: #444;
  padding: 1rem;
  width: 27rem;
}
.username {
  color: white;
  font-size: 1.3rem;
}

这样,我们就完成了表单的创建!您应该看到如下内容:

结论

在本文中,我们了解了react-mentions一个易于使用的库,用于构建具有@mention功能的表单。我们还研究了react-mentions包的不同功能以及我们如何使用它们。我们还使用该包构建了一个具有@mention功能的评论表单。react-mentiom

你可能感兴趣的:(react.js,前端,javascript)