【问题标题】:onChange event impacts String length (Sanitizer)onChange 事件影响字符串长度(消毒剂)
【发布时间】:2020-11-30 16:26:28
【问题描述】:

我目前正在研究一个输入标签,它将用户输入格式化并修复为正确的日期时间格式。
目前,除了数字之外的任何内容都不会被格式化为日期。

例如:11302020 => 11 / 30 / 2020

现在我想为日、月、年设置字符串部分的范围。
如果用户超过限制,数字(或字符串的一部分)将被清理。
我的函数将输入字符串切成块,因此我可以将值写入新数组。
然而,最后我的切碎数组有 a) 大小为 6b) 总字符长度为 15。
当我将这些条件放在 if 问题中以将这些值保存在单独的部分中时,它开始以 16 的字符长度保存,这意味着,在用户输入完整日期和附加字符后,这不是什么我想要我的(b)。有人可以帮帮我吗?

import React, { useState } from "react";

// export const dateFormatter = (input) => {
//   return input;
// };

export default function App() {
  const [maskedState, setMaskedState] = useState("");

  const dateFormatter = (date) => {
    setMaskedState(date.replace(/\D/g, "")
      .replace(/(\d{2})(\d)/, " $1 / $2")
      .replace(/(\d{2})(\d)/, "$1 / $2")
      .replace(/(\d{4})\d+?$/, "$1"));

    const maskedStateStr = maskedState.split(" ");
    const charLength = 15;
    const arrLength = 6;

   if ((maskedStateStr.length === arrLength) && (maskedState.length === charLength)){
    maskedStateStr.shift();
    var day = maskedStateStr[0];
    var month = maskedStateStr[2];
    var year = maskedStateStr[4];

   console.log(day,month,year);
   }

   //console.log(maskedStateStr, maskedStateStr.length, maskedState, maskedState.length)
    
  }

  const handleInput = (date) => {
    const inputValue = date.target.value;
    dateFormatter(inputValue);
  };

  return (
    <div className="App">
      <input onChange={handleInput} value={maskedState} />
    </div>
  );
}

【问题讨论】:

    标签: javascript reactjs input label onchange


    【解决方案1】:

    该代码有很多问题,但我只关注react 的一部分。

    • setMaskedState 不会立即更新 maskedState,因此 maskedState 很可能会指向陈旧状态。
    • 在输入上设置value 会使其无法编辑,因此您甚至看不到您正在输入的内容。使用defaultValue

    也就是说,您应该对 date 值进行操作,并且只在块末尾设置状态以反映结果。喜欢:

    export default function App() {
      const [maskedState, setMaskedState] = useState(null);
    
      const dateFormatter = value => {
        let formattedDate = value
          .replace(/\D/g, "")
          .replace(/(\d{2})(\d)/, " $1 / $2")
          .replace(/(\d{2})(\d)/, "$1 / $2")
          .replace(/(\d{4})\d+?$/, "$1");
    
        const maskedStateStr = formattedDate.split(" ");
        const charLength = 15;
        const arrLength = 6;
    
        if (
          maskedStateStr.length === arrLength &&
          formattedDate.length === charLength
        ) {
          maskedStateStr.shift();
          let day = maskedStateStr[0];
          let month = maskedStateStr[2];
          let year = maskedStateStr[4];
          setMaskedState(`${day} / ${month} / ${year}`);
        } else {
          setMaskedState(value);
        }
      };
    
      const handleInput = date => {
        const inputValue = date.target.value;
        dateFormatter(inputValue);
      };
    
      return (
        <div className="App">
          <input onChange={handleInput} value={maskedState} />
          <pre>
            <code>
              {maskedState
                ? JSON.stringify(maskedState, null, 2)
                : "Not a valid date yet"}
            </code>
          </pre>
        </div>
      );
    }
    
    
    

    demo on StackBlitz

    【讨论】:

    • 感谢您提供干净的代码,但现在我的输入没有自动格式化?
    • @LaFllamme,更新了答案。现在应该修好了,祝你好运。
    猜你喜欢
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2021-03-06
    • 1970-01-01
    相关资源
    最近更新 更多