如何避免在 useEffect 中使用 setState?

问题描述 投票:0回答:1
useEffect(() => {
    if (processed.length !== Object.keys(rules).length) {
      if (currRules.length) {
        const done = [],
          notDone = [];
        currRules.forEach((rule) => {
          const regex = new RegExp(rule);
          if (regex.test(password)) {
            if (rules[rule] === "The password digits should add upto 11") {
              console.log(rules[rule]);
              let chars = [...password],
                sum = 0;
              chars.forEach((char) => {
                console.log(Number(char));
                if (Number(char)) {
                  sum += Number(char);
                }
              });
              if (sum === 11) {
                done.push(rule);
              }
            } else {
              done.push(rule);
            }
          } else {
            notDone.push(rule);
          }
        });
        setProcessed([...processed, ...done]);
        setCurrRules([...notDone]);
      } else {
        for (const rule in rules) {
          if (!processed.includes(rule) && password) {
            setCurrRules([rule]);
            break;
          }
        }
      }
    }
    if (!password) {
      setCurrRules([...processed]);
      setProcessed([]);
    }
  }, [password, currRules]);

我有一个存储密码的输入字段,我正在尝试匹配一些以

rules
格式存储在
{".{6,}": "The password should be minimum 6 characters", ...}
中的密码正则表达式规则。根据规则是否匹配,规则会在密码字段下方显示为绿色或红色。我将它们一一匹配,并在匹配时将它们存储在
processed
中。
currRules
具有正在检查的当前规则。问题是我遇到了无限循环,因为我必须使用 setState 来更新 useEffect 中的当前和已处理的规则。如何重新配置我的代码以免遇到此问题?

javascript reactjs react-hooks
1个回答
0
投票

您在 useEffect 内遇到无限循环的问题是由于 setState 调用造成的,它会触发重新渲染并重新调用 useEffect,从而创建一个循环

useEffect(() => {
  if (!password) {
    setCurrRules([]);
    setProcessed([]);
    return;
  }

  if (processed.length === Object.keys(rules).length) return;

  if (!currRules.length) {
    const nextRule = Object.keys(rules).find(rule => !processed.includes(rule));
    if (nextRule) {
      setCurrRules([nextRule]);
    }
    return;
  }

  const [currentRule] = currRules;
  const regex = new RegExp(currentRule);

  if (regex.test(password)) {
    if (rules[currentRule] === "The password digits should add up to 11") {
      const sum = password.split('').reduce((acc, char) => acc + (Number(char) || 0), 0);
      if (sum === 11) {
        setProcessed(prev => [...prev, currentRule]);
      }
    } else {
      setProcessed(prev => [...prev, currentRule]);
    }
    setCurrRules([]);
  } else {

    setCurrRules([]);
  }
}, [password, currRules, processed, rules]);

© www.soinside.com 2019 - 2024. All rights reserved.