Reactjs 中的 useEffect 验证

useEffect validation in Reactjs

所以我对反应还很陌生,我现在正在尝试制作一个密码键盘屏幕,但我卡住了。 我不知道如何在我的应用程序中使用 useEfect 来验证 4 位数的 pin, 比如,我只是很困惑在哪里以及如何编写它以便它实际工作,是否有任何示例以便我可以看到如何去做?

    export default function App() {
  const [pin, setPin] = useState("");

  return (
    <div>
      <div>{pin}</div>
      <div>
        <div>
          <button onClick={() => setPin((pin) => `${pin}1`)}>1</button>
          <button onClick={() => setPin((pin) => `${pin}2`)}>2</button>
          <button onClick={() => setPin((pin) => `${pin}3`)}>3</button>
        </div>
        <div>
          <button onClick={() => setPin((pin) => `${pin}4`)}>4</button>
          <button onClick={() => setPin((pin) => `${pin}5`)}>5</button>
          <button onClick={() => setPin((pin) => `${pin}6`)}>6</button>
        </div>
        <div>
          <button onClick={() => setPin((pin) => `${pin}7`)}>7</button>
          <button onClick={() => setPin((pin) => `${pin}8`)}>8</button>
          <button onClick={() => setPin((pin) => `${pin}9`)}>9</button>
        </div>
        <div>
          <button onClick={() => setPin((pin) => pin.slice(0, pin.length - 1))}>
            &lt;
          </button>
          <button onClick={() => setPin((pin) => `${pin}0`)}>0</button>
          <button onClick={() => setPin("")}>C</button>
        </div>
      </div>
    </div>
  );
}

您可以添加 useEffect 挂钩 pin 作为依赖项:

useEffect(() => {
 console.log(pin, pin.length)
}, [pin])

每次 pin 更改时都会调用传递给 useEffect 的回调

要在状态更改时验证任何反应状态,您可以像这样使用 useEffect

useEffect(() => {
   // pin state changed
}, [pin]);

useEffect 可以在组件挂载、卸载或任何状态变量发生变化时使用。在方括号内使用的变量(本例中为 pin)称为因变量。这意味着当这个变量发生变化时,它将 运行 该特定代码。

更多React useEffect hook

只需使用 useEffect 依赖数组检查您的 pin 状态的变化,然后在达到四位数时记录保存的 PIN。

在这个例子中,我使用了一个数组来存储我然后 join 的数字。 (我还冒昧地使用了 CSS Grid 和一个 Button 组件,因此代码尽可能干)。

const { useEffect, useState } = React;

function Example({ test }) {

  const [ pin, setPin ] = useState('');
  const [ attempt, setAttempt ] = useState(0);
  const [ lock, setLock ] = useState(false);
  const [ message, setMessage ] = useState('');

  // Reset the state if the "number" is "C"
  // otherwise add the number to the state string
  function handleClick(e) {
    const { number } = e.target.dataset;
    if (number === 'C') {
      setPin([]);
    } else {
      setPin(`${pin}${number}`);
    }
  }

  // If the pin state has changed,
  // and the length of the array is four,
  // log the state
  useEffect(() => {
    if (attempt < 3) {
      if (pin.length === 4) {
        if (pin !== test) {
          setAttempt(attempt + 1);
          setPin('');
          setMessage('Incorrect PIN.');
          setTimeout(() => setMessage(''), 2000);

        } else {
          setMessage('PIN accepted');
        }
      }
    } else {
      setMessage('Failed to log in.');
      setLock(true);
      setTimeout(() => setLock(false), 3000);
    }
  }, [pin]);

  function maskedPin() {
    let str = '';
    for (let i = 0; i < pin.length; i++) {
      str += '*';
    }
    return str;
  }

  // Create a new array and map over the elements
  // to create some buttons
  return (
    <div>
      <div class="grid">
        {new Array(9).fill('').map((el, i) => (
          <Button lock={lock} number={i + 1} handleClick={handleClick} />
        ))}
        <Button lock={lock} number="0" handleClick={handleClick} />
        <Button lock={lock} number="C" handleClick={handleClick} />
      </div>
      <div class="pin">{maskedPin()}</div>
      <div class="message">{message}</div>
    </div>
  );
}

function Button({ lock, number, handleClick }) {
  return (
    <button
      disabled={lock}
      data-number={number}
      onClick={handleClick}
    >{number}</button>
  );
}

ReactDOM.render(
  <Example test="1234" />,
  document.getElementById('react')
);
.grid { width: 100px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.message { margin-top: 0.5em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>