React 如何使用 useEffect 和 useCallback 重新渲染状态挂钩?

React How to re-render state hook with useEffect and useCallback?

很抱歉问了这个问题。我已经阅读了很多关于如何重新渲染状态的帖子,但我仍然无法弄清楚。我太菜鸟了:( 我可以使用 useRef 进行操作,但我想了解如何使用 useEffect 和 useCallback 更新状态。 我的数据库提取需要第二次点击才能触发,因为 setState 是异步的。我的 useEffect/useCallback 都没有更新状态 :( useEffect 正在触发,我正在获取控制台日志。

export function Form() {
    const[inputKey, setInputKey] = useState("");
    const inputKeyRef = useRef();

    const [keyValid, setKeyValid] = useState(false);
    useEffect(() => {
        console.log("keyValid:", keyValid)
    }, [keyValid])

    const [keyAuthentic, setKeyAuthentic] = useState(false);
    useEffect(() => {
        console.log("keyAuthentic:", keyAuthentic)
    }, [keyAuthentic])

    const updateKeyValid = useCallback(
        () => setKeyValid(true),
        [keyValid, setKeyValid]
    )

    const submit = e => {
        e.preventDefault();
        if ( !inputKeyRef.current.value.length < 12 || !inputKeyRef.current.value.length < 20 ) {
            setKeyValid(true) // not updating state
            updateKeyValid(); // not updating state
        }

        if ( keyValid === true ) { // state not true if keyValid(true)
            db.collection("users").doc(inputKey).get().then((doc) => {
                if (doc.exists) {
                    setKeyAuthentic(true)
                    console.log(doc.data())
                }
            });
        }
    };

    return (
        <div className="form__submit">
            <Button type="submit" onClick={submit}}>Submit</Button>
        </div>
    )
}

export default Form

如您所述,setKeyValid 是异步的,因此在下一次渲染之前您将无法访问新值。

您的效果不调用任何 setState 函数,所以我不确定您为什么期望在它们内部更新状态。

此外,状态不应该是确定性的。如果您可以根据某些其他状态确定任何渲染上的值应该是什么,那么您根本不需要 useState。喜欢:

export function Form() {
  const [keyAuthentic, setKeyAuthentic] = useState(false);
  const [inputKey, setInputKey] = useState("");

  const submit = e => {
      e.preventDefault();
      
      const valid = !inputKey.length < 12 || !inputKey.length < 20;
      if (!valid) return;

      db.collection("users").doc(inputKey).get().then((doc) => {
          if (doc.exists) {
              setKeyAuthentic(true)
              console.log(doc.data())
          }
      });
  };

  return (
      <div className="form__submit">
          <Button type="submit" onClick={submit}}>Submit</Button>
      </div>
  )
}