代码之家  ›  专栏  ›  技术社区  ›  bp123

使用钩子时等待状态更新

  •  0
  • bp123  · 技术社区  · 7 年前

    如何使用钩子等待状态更新。当我提交表格时,我需要检查一下 termsValidation 在运行其他代码之前为false。如果国家刚刚改变了,它就不会注意到这一点。

    import React, { useState } from 'react';
    
    export default function Signup() {
      const [terms, setTerms] = useState('');
      const [termsValidation, setTermsValidation] = useState(false);
    
      function handleSubmit(e) {
        e.preventDefault();
    
        if (!terms) {
          setTermsValidation(true);
        } else {
          setTermsValidation(false);
        }
    
        if (!termsValidation) {
          console.log('run something here');
        }
      }
    
      return (
        <div>
          <form>
            <input type="checkbox" id="terms" name="terms" checked={terms} />
    
            <button type="submit" onClick={handleSubmit}>
              Sign up
            </button>
          </form>
        </div>
      );
    }
    
    2 回复  |  直到 7 年前
        1
  •  20
  •   DoHn    7 年前

    这个 useState hook是异步的,但它没有像这样的回调api setState 做。如果要等待状态更新,则需要 useEffect 挂钩:

    import React, { useState, useEffect } from 'react';
    
    export default function Signup() {
      const [terms, setTerms] = useState('');
      const [termsValidation, setTermsValidation] = useState(false);
    
      useEffect(() => {
        if (!termsValidation) {
          console.log('run something here');
        }
      }, [termsValidation]);
    
      function handleSubmit(e) {
        e.preventDefault();
    
        if (!terms) {
          setTermsValidation(true);
        } else {
          setTermsValidation(false);
        }
      }
    
      return (
        <div>
          <form>
            <input type="checkbox" id="terms" name="terms" checked={terms} />
    
            <button type="submit" onClick={handleSubmit}>
              Sign up
            </button>
          </form>
        </div>
      );
    }
    
        2
  •  15
  •   Gianfranco Fertino    5 年前

    像这样改变状态 setTermsValidation 是异步操作,这意味着它不是立即的,程序不会等待它。它会开火然后忘记。因此,当你打电话 setTermsValidation(true) 程序将继续运行下一个块,而不是等待termValidation变为true。这就是为什么termsValidation仍然具有旧值的原因。

    你可以这样做

    function handleSubmit(e) {
        e.preventDefault();
    
        if (!terms) {
          setTermsValidation(true);
        } else {
          setTermsValidation(false);
          // assuming you want to run something when termsvalidation turn to false
          console.log('run something here');
        }
    }
    

    或者最好用钩子 useEffect()

    useEffect(() => {
        if (!termsValidation) {
          console.log('run something here');
        }
    }, [termsValidation]);
    

    但是,要小心,因为useffect也会在初始渲染时运行。