useState在调度异步thunk后不会更新.catch中的状态。

huangapple go评论65阅读模式
英文:

useState does not update the state within .catch after dispatching of asynk thunk

问题

在上面的代码中,setError 在从 redux-toolkit 的异步 thunk 后的 catch 中未更新 error

  const [error, setError] = useState("");
  const handleLogin = () => {
    dispatch(userLogin({ email, password }))
      .unwrap()
      .then(() => {
        if (userInfo) {
          navigate("/profile");
        }
      })
      .catch((err) => {
        setError(err); // 无法正常工作
      });
  };
<button onClick={handleLogin}>登录</button>
export const userLogin = createAsyncThunk(
  "auth/login",
  async ({ email, password }, thunkAPI) => {
    try {
      const { data } = await userLoginRequest(email, password);
      return data;
    } catch (error) {
      return thunkAPI.rejectWithValue(ERR_USER_LOGIN); 
      // ERR_USER_LOGIN 只是来自另一个文件的常量字符串
    }
  }
);

我知道 useState 不会立即应用更改,但在我的情况下,它根本忽略了更改。我认为问题可能与作用域或类似的东西有关。因此,我尝试使用额外的回调,将其作为参数发送,并通过它更改状态,但这也不起作用。

英文:

In the following code setError does not update error in the catch after async thunk from redux-toolkit.

  const [error, setError] = useState(&quot;&quot;);
  const handleLogin = () =&gt; {
    dispatch(userLogin({ email, password }))
      .unwrap()
      .then(() =&gt; {
        if (userInfo) {
          navigate(&quot;/profile&quot;);
        }
      })
      .catch((err) =&gt; {
        setError(err) // does not work
      });
  };
&lt;button onClick={handleLogin}&gt;Login&lt;/button&gt;
export const userLogin = createAsyncThunk(
  &quot;auth/login&quot;,
  async ({ email, password }, thunkAPI) =&gt; {
    try {
      const { data } = await userLoginRequest(email, password);
      return data;
    } catch (error) {
      return thunkAPI.rejectWithValue(ERR_USER_LOGIN); 
      // ERR_USER_LOGIN is just a constant string from another file
    }
  }
);

I know that useState does not apply changed immediatly but in my case it ignores changes at all. I suppose that the problem can be related to the scope or something like this. So I've tried to use additional callback which I sent as a parameter and change the state through it but it also does not work.

答案1

得分: 1

你的userLogin函数实际上已经捕获了错误,导致handleLogin无法捕获任何内容。
你可以在userLogin内部抛出错误,这样handleLogin就可以自行捕获错误。

export const userLogin = createAsyncThunk(
  "auth/login",
  async ({ email, password }, thunkAPI) => {
    try {
      const { data } = await userLoginRequest(email, password);
      return data;
    } catch (error) {
      thunkAPI.rejectWithValue(ERR_USER_LOGIN); 
      // 添加这行
      throw error;
    }
  }
);
英文:

Your userLogin function actually has caught the error, making handleLogin catch not catch anything.
You can throw the error within userLogin, so handleLogin can catch the error by itself.

export const userLogin = createAsyncThunk(
  &quot;auth/login&quot;,
  async ({ email, password }, thunkAPI) =&gt; {
    try {
      const { data } = await userLoginRequest(email, password);
      return data;
    } catch (error) {
      thunkAPI.rejectWithValue(ERR_USER_LOGIN); 
      // Add this
      throw error;
    }
  }
);

huangapple
  • 本文由 发表于 2023年2月18日 09:55:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75490708.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定