为什么 setState 回调会抛出错误:“来自 useState() 和 useReducer() Hook 的状态更新不支持第二个回调参数...”

She*_* Mi 2 javascript callback reactjs

我正在尝试创建一个 setState 回调,因为 setState 是异步的,并且我想在之后安全地使用该状态。

function Register(props) {
    const [errMsg, setErrMsg] = useState(null);
    
    const fullNameInputRef = useRef();
    const emailInputRef = useRef();
    const passwordInputRef = useRef();


    function submitHandler(event) {
        event.preventDefault(); //prevents full page reload
        
        const enteredFullName = fullNameInputRef.current.value;
        const enteredEmail= emailInputRef.current.value;
        const enteredPassword = passwordInputRef.current.value;

        axios({
            method: 'post',
            url: 'http://localhost:3000/api/users/register',
            data: {
              username: enteredFullName,
              email: enteredEmail,
              password: enteredPassword
            }
          }).then( (res) => {
              if (res.data.success == false) {
                  setErrMsg(`${res.data.message}`, () => {  /* setState Callback */
                    console.log(errMsg);
                  });
              }
              else { console.log(res)}
          }).catch( (err) => {
              console.log(err)
              setErrMsg("An error has occured. Please try again later")
          });
    
      }
Run Code Online (Sandbox Code Playgroud)

但是回调中的console.log不起作用。( console.log(errMsg); ) 我收到以下错误:

警告:来自 useState() 和 useReducer() Hook 的状态更新不支持第二个回调参数。要在渲染后执行副作用,请使用 useEffect() 在组件主体中声明它。

我缺少什么?

Den*_*ash 8

与错误状态一样,setState钩子不支持像类组件中的第二个参数:

// BAD, WRONG API
setErrMsg(`${res.data.message}`, () => console.log(errMsg));
Run Code Online (Sandbox Code Playgroud)

相反,添加一个useEffect

// GOOD
setErrMsg(`${res.data.message}`);

useEffect(() => {
  console.log(errMsg);
}, [errMsg]
Run Code Online (Sandbox Code Playgroud)

完整代码:

function Register(props) {
    const [errMsg, setErrMsg] = useState(null);
    
    ...

    useEffect(() => {
        console.log(errMsg);
    }, [errMsg]


    function submitHandler(event) {
        ...

        axios({ ... }).then((res) => {
              if (res.data.success == false) {
                  setErrMsg(`${res.data.message}`);
              }
              else { console.log(res)}
          }).catch( (err) => {
              console.log(err)
              setErrMsg("An error has occured. Please try again later")
          });
      }

   return <>...</>
}
Run Code Online (Sandbox Code Playgroud)

  • 阅读新错误,您需要在顶层调用 `useEffect`,而不是在函数内部,请阅读文档。 (2认同)