RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1244676
Accepted
118_64
118_64
Asked:2022-02-16 19:33:44 +0000 UTC2022-02-16 19:33:44 +0000 UTC 2022-02-16 19:33:44 +0000 UTC

在 ReactJS 中输入输入时如何防止失去焦点?

  • 772

有一个使用 创建的表单React,当输入到 field 时name,会将值写入状态。输入任何字符后,该字段失去焦点。我知道useState刷新页面,这就是原因。

input为了解决这个问题,我为字段和外部元素都分配了键。结果是一样的。尝试添加input为外部元素,但表单不断更新。

所有代码都在这里发布:https ://codesandbox.io/s/me08n

我寻求有关如何在不重新加载输入的情况下创建表单的帮助和建议。下面是创建表单的文件的代码。

form.js:

import axios from "axios";

function Form({ data, funct }) {
  const HandleImageUpload = () => {
    const handleImage = (e) => {
      const target = imageLoader.files[0];
      const type = target.type.split("/");
      const typeArr = ["jpg", "jpeg", "gif", "png"];

      if (!typeArr.includes(type[1])) {
        funct.setButtonValue("Недопустимый формат");
        return;
      } else {
        funct.setButtonValue("Изображение загружено");
      }

      const reader = new FileReader();
      reader.readAsDataURL(e.target.files[0]);

      reader.onload = function (event) {
        const image = new Image();
        image.src = event.target.result;

        image.onload = function () {
          let imgWidth = image.width;
          let imgHeight = image.height;
          const orientation = imgWidth / imgHeight;

          if (imgHeight > 240 || imgWidth > 320) {
            if (orientation <= 1 || imgHeight * (320 / imgWidth) > 240) {
              imgWidth = imgWidth * (240 / imgHeight);
              imgHeight = 240;
            } else {
              imgHeight = imgHeight * (320 / imgWidth);
              imgWidth = 320;
            }
          }

          const canvas = document.createElement("canvas");
          const ctx = canvas.getContext("2d");
          canvas.width = imgWidth;
          canvas.height = imgHeight;
          ctx.drawImage(image, 0, 0, imgWidth, imgHeight);

          const preview = new Image(imgWidth, imgHeight);
          preview.src = canvas.toDataURL("image/jpeg", 1.0);
          funct.setImage(preview.src);
        };
      };
    };

    const imageLoader = document.getElementById("image_loader");
    imageLoader.addEventListener("change", handleImage, false);
    imageLoader.click();
  };

  const handleNameValidation = (e) => {
    if (e.target.value.match(/[^0-9A-Z a-z]/gi)) {
      e.target.value = e.target.value.replace(/[^0-9A-Z a-z]/gi, "");
    }
  };

  const handleEmailOnBlurValidation = (e) => {
    const reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,})$/;

    if (!e.target.value.match(reg) && e.target.value != "") {
      funct.setErrors("Ошибка! Введите правильный email.");
      return false;
    }

    const checkingMailOriginality = async () => {
      axios.post(`/check`, {}).then((res) => {
        if (res.data !== 0) {
          funct.setErrors("Вы уже комментировали. Допустим только один отзыв!");
        } else {
          funct.setMail(data);
        }
      });
    };
    // checkingMailOriginality();
  };

  const handleHomePageValidation = (e) => {
    e.target.value = e.target.value
      .toLowerCase()
      .replace("https://", "")
      .replace("http://", "");
  };

  const handleFeedbackSend = async (e) => {
    e.preventDefault();

    if (!data.name || !data.mail || !data.feedback || data.errors) {
      return;
    }

    const feedbackData = {
      name: data.name,
      mail: data.mail,
      page: data.homePage,
      feedback: data.feedback,
      image: data.image
    };

    const path = "/add";

    const response = await fetch(path, {
      method: "POST",
      headers: {
        "Content-Type": "application/json;charset=utf-8"
      },
      body: JSON.stringify(feedbackData)
    });

    const result = await response.text();
    document.location.href = "/";
  };

  const handleEmailOnInput = (e) => {
    e.target.value = e.target.value.toLowerCase();
    if (e.target.value.match(/[^@0-9a-z-\.]/gi)) {
      e.target.value = e.target.value.replace(/[^@0-9a-z-\.]/gi, "");
    }
  };

  return (
    <div className="feedbackForm" key="formKey4">
      <form onSubmit={handleFeedbackSend} key="formKey3">
        <h2>Мой комментарий:</h2>

        <i
          id="closeForm"
          className="material-icons closeForm"
          onClick={() => funct.setShowComponent("startButton")}
        >
          clear
        </i>

        <div className="error">{data.errors}</div>

        <span className="formContainer" key="formKey1">
          <label key="lKey1">
            Имя (на английском):
            <input
              key="key1"
              name="name"
              type="text"
              maxLength="40"
              required
              placeholder="e.g. Piter"
              defaultValue={data.name}
              onInput={(e) => {
                handleNameValidation(e);
                funct.setName(e.target.value);
              }}
            />
          </label>

          <label key="lKey2">
            E-mail:
            <input
              key="key2"
              id="email"
              name="mail"
              type="text"
              required
              maxLength="40"
              placeholder="mail@example.com"
              defaultValue={data.mail}
              onInput={(e) => {
                handleEmailOnInput(e);
                funct.setErrors("");
              }}
              onBlur={(e) => {
                funct.setMail(e.target.value);
                handleEmailOnBlurValidation(e);
              }}
            />
          </label>

          <label key="lKey3">
            Моя домашняя страница:
            <input
              key="key3"
              name="page"
              type="text"
              maxLength="100"
              placeholder="example.com"
              defaultValue={data.homePage}
              onInput={handleHomePageValidation}
              onBlur={(e) => funct.setHomePage(e.target.value)}
            />
          </label>
        </span>

        <label key="lKey4">
          Текст комментария:
          <textarea
            key="key4"
            className="textareaForm"
            maxLength="800"
            required
            defaultValue={data.feedback}
            onBlur={(e) => funct.setFeedback(e.target.value)}
          ></textarea>
        </label>

        <span className="formContainer" key="formKey2">
          <input key="key5" id="image_loader" type="file" hidden />

          <input
            key="key6"
            id="upload"
            type="button"
            className="buttonSubmit"
            defaultValue={data.buttonValue}
            onClick={HandleImageUpload}
          />

          <input
            key="key7"
            type="button"
            className="buttonSubmit"
            defaultValue="Предварительный просмотр"
            onClick={() => funct.setShowComponent("preview")}
          />

          <input
            key="key8"
            id="feedback_send"
            type="submit"
            className="buttonSubmit"
            defaultValue="Опубликовать"
          />
        </span>
      </form>
    </div>
  );
}

export default Form;
reactjs
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    118_64
    2022-02-16T21:30:56Z2022-02-16T21:30:56Z

    为了避免更新表单,您需要删除渲染内部的函数调用。

    是这样的:

     const FeedbackForm = () =>
        showComponent === "form" ? <Form data={data} funct={funct} /> : null;
    
      const FeedbackPreview = () =>
        showComponent === "preview" ? (
          <FeedbackRowPreview data={data} setShowComponent={setShowComponent} />
        ) : null;
    
      return (
        <div className="App">
          <h1>Гостевая книга</h1>
          <main>
            <StartButton />
            <ul className="feedbackList">
              <FeedbackPreview />
              <FeedbackForm />
            </ul>
          </main>
        </div>
      );
    

    它变成了这样:

      const feedbackFormNode =
        showComponent === "form" ? <Form data={data} funct={funct} /> : null;
    
      const feedbackPreviewNode =
        showComponent === "preview" ? (
          <FeedbackRowPreview data={data} setShowComponent={setShowComponent} />
        ) : null;
    
      return (
        <div className="App">
          <h1>Гостевая книга</h1>
          <main>
            {StartButtonNode}
            <ul className="feedbackList">
              {feedbackFormNode}
              {feedbackPreviewNode}
            </ul>
          </main>
        </div>
      );
    }
    

    输入输入时不会重绘整个表单。

    • 0

相关问题

  • 如果图像在道具中,如何使背景图像做出反应?

  • 项目未显示

  • 引发错误:InvalidTokenError: Invalid token specified: Cannot read property 'replace' of undefined

  • 如何在没有 node.js 的情况下运行 react.js 应用程序

  • 如何从 React Native 中的导航堆栈中清除上一个屏幕?

  • 为什么渲染后会触发 Click 事件?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5