В этом блоге я хотел бы обсудить извлечение хэштега из формы, созданной с помощью Formik. Код, который я предоставлю позже в этой статье, будет включать довольно простую функцию хэштега. На входе самой формы к хэштегам не прикреплены элементы стиля. Основная предпосылка заключается в том, что пользователь создаст сообщение, используя хэштег или нет; однако, если они это сделают, форма распознает этот хэштег и сравнит его с существующими хэштегами в веб-приложении, а при совпадении продолжит отправку формы, в конечном итоге отображая публикацию на странице без хэштега.

В своем приложении я использую слово «район» для обозначения темы или хэштега. Есть районные страницы, на которых публикуются сообщения с этим конкретным хэштегом. Вот что я имею в виду…

Обратите внимание, что на главной странице большинство сообщений имеют хэштеги с названиями районов, чтобы указать, к какому району относится сообщение. Итак, что происходит, когда пост, созданный здесь, не содержит хэштега? Ну, это также будет рассмотрено в блоке кода ниже. Но, прежде чем я дам товар, вот снимок используемой формы публикации.

Вот код…

  const validationSchema = yup.object({
    post: yup.string("Enter post").required("Post is required"),
  });
  const formik = useFormik({
    initialValues: {
      post: "",
    },
    validationSchema: validationSchema,
    onSubmit: (values, { setSubmitting }) => {
      setSubmitting(true);

      const hashtagMatches = values?.post.match(/#\w+/gi);

      const hashtags = hashtagMatches
        ? hashtagMatches.map((tag) => tag.toLowerCase().slice(1))
        : [];

      const filteredTags = districts?.filter((district) => {
        if (
          hashtags.some((hashtag) =>
            district.name.toLowerCase().includes(hashtag)
          )
        ) {
          return district.id;
        }
      });

      if (filteredTags && filteredTags.length > 0) {
        idDistrict = filteredTags[0].id;
      }

      const newValues = {
        ...values,
        post: values.post.replace(/#\w+/gi, "").trim(),
      };

      const submission = {
        ...newValues,
        user_id: userId,
        votes: 0,
        district_id: idDistrict,
      };
      fetch("/createpost", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(submission),
      }).then((res) => {
        if (res.ok) {
          res.json().then((postData) => {
            fetchPost();
            setShowCreatePost(false);
            setSubmitting(false);
          });
        }
      });
    },
  });

Теперь давайте рассмотрим, что делают некоторые из незнакомых строк.

const hashtagMatches = values?.post.match(/#\w+/gi);

В этой строке используется необязательная цепочка; Вы можете прочитать больше об этом здесь". Эта строка проверяет, существует ли 'value.post', а затем сопоставляет все хэштеги в формате '#\w+' с глобальные и чувствительные к регистру флаги. Затем совпадения назначаются hashtagMatches.

const hashtags = hashtagMatches
        ? hashtagMatches.map((tag) => tag.toLowerCase().slice(1))
        : [];

В приведенных выше строках кода цель состоит в том, чтобы создать массив хэштегов. Если 'hashtagMatches' не равно null,сопоставьтекаждое совпадение (тег) в'hashtagMatches'. Затем он преобразует тег в нижний регистр и удаляет символ '#' путем нарезки из индекса 1. Если 'hashtagMatches' равно null , он назначит пустой массив для 'хэштегов'.

const filteredTags = districts?.filter((district) => {
        if (
          hashtags.some((hashtag) =>
            district.name.toLowerCase().includes(hashtag)
          )
        ) {
          return district.id;
        }
      });

Следующая функция отфильтрует массив «районы», чтобы получить «filteredTags». Небольшое примечание о массиве «районы»; этот массив был выбран в родительском компоненте, а затем передан моему компоненту CreatePost. Затем он снова проверяет, существуют ли «районы», используя необязательную цепочку. Он фильтрует каждый «район» в «районах», проверяя, включен ли какой-либо хэштег в «хэштеги» в название района. Если true, возвращается 'district.id'; если «районы» не существуют, «filteredTags» будет неопределенным.

if (filteredTags && filteredTags.length > 0) {
        idDistrict = filteredTags[0].id;
      }

Эта функция проверяет, не является ли «filteredTags» null и содержит ли хотя бы один элемент. Если true, назначьте «id» первого элемента в «filteredTags» для «idDistrict».

const newValues = {
        ...values,
        post: values.post.replace(/#\w+/gi, "").trim(),
      };

Наконец, в этой части блока кода хэштеги из values.post удаляются, обрезая результат. Он заменяет все хэштеги в формате ‘#\w+’ пустой строкой, используя регулярное выражение с глобальными и чувствительными к регистру флагами. Используя trim(), он обрезает результирующую строку, удаляя все начальные или конечные пробелы. Наконец, он создает новый объект с именем newValues со всеми свойствами из values и обновленным полем post.

В этом суть. Если вам нужна прокомментированная версия блока кода выше для лучшего понимания, ознакомьтесь с ней ниже!

  // Set the submitting state to true
  setSubmitting(true);

  // Find all hashtag matches in the post
  const hashtagMatches = values?.post.match(/#\w+/gi);
  
  // Process the matched hashtags (lowercase and remove '#')
  const hashtags = hashtagMatches
    ? hashtagMatches.map((tag) => tag.toLowerCase().slice(1))
    : [];

  // Filter districts based on whether any hashtag includes the district name
  const filteredTags = districts?.filter((district) => {
    if (
      hashtags.some((hashtag) =>
        district.name.toLowerCase().includes(hashtag)
      )
    ) {
      // Return district id if the district name includes a hashtag
      return district.id;
    }
  });

  // If there are filtered tags, set idDistrict to the first district's id
  if (filteredTags && filteredTags.length > 0) {
    idDistrict = filteredTags[0].id;
  }

  // Remove hashtags from the post and trim the result
  const newValues = {
    ...values,
    post: values.post.replace(/#\w+/gi, "").trim(),
  };

  // Create the submission object with newValues, user_id, votes, and district_id
  const submission = {
    ...newValues,
    user_id: userId,
    votes: 0,
    district_id: idDistrict,
  };

  // Send a POST request to the "/createpost" endpoint
  fetch("/createpost", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(submission),
  }).then((res) => {
    // If the response is ok, process the response JSON
    if (res.ok) {
      res.json().then((postData) => {
        // Call the fetchPost function
        fetchPost();
        
        // Set setShowCreatePost to false
        setShowCreatePost(false);
        
        // Set the submitting state to false
        setSubmitting(false);
      });
    }
  });
},

Вот результат кода:

В любом случае, я надеюсь, что это было полезно! Дайте мне знать, если у вас есть какие-либо советы или вопросы, и если вы хотите ознакомиться с моим демо-проектом, вот ссылка.

До скорого!

-Триша