【问题标题】:Redux-Toolkit dispatch in useEffect hook results in an infinite loopuseEffect 挂钩中的 Redux-Toolkit 分派导致无限循环
【发布时间】:2022-11-30 10:52:51
【问题描述】:

问题

我使用来自 react-query 的 useMuation 来执行发布请求并从 JSON 获取用户信息,然后尝试根据 react-query useMutation hook 给出的状态使用 useEffect 将其存储到我的 redux 存储中,这是成功的。问题出现在这种状态。正如您在图片中看到的那样,所有信息都已成功存储在 redux 存储中,但它会导致无限循环。

我试着放一个空的依赖数组,甚至放 userData?.data?.data?.user?.nameuserData?.data?.token 而不是 userData 但还是一样。

错误

店铺

用户切片.ts

import { createSlice, configureStore, PayloadAction } from "@reduxjs/toolkit";

type initialState = {
  user: string;
  dashboardIndex: number;
  theme: string;
  token: string;
  isLoggedIn: boolean;
};

const initialState: initialState = {
  user: "",
  dashboardIndex: 0,
  theme: "themeLight",
  token: "",
  isLoggedIn: false,
};

const userSlice = createSlice({
  name: "user",
  initialState: initialState,
  reducers: {
    updateUser(state, action: PayloadAction<string>) {
      state.user = action.payload;
    },
    updateDashboardIndex(state, action: PayloadAction<number>) {
      state.dashboardIndex = action.payload;
    },
    updateTheme(state, action: PayloadAction<string>) {
      state.theme = action.payload;
    },
    updateToken(state, action: PayloadAction<string>) {
      state.token = action.payload;
    },
    updateIsLoggedIn(state, action: PayloadAction<boolean>) {
      state.isLoggedIn = action.payload;
    },
    reset: () => initialState,
  },
});

// ...

登录.tsx

const LoginComponents = () => {
  let navigate = useNavigate();
  const [loginObject, setLoginOject] = useState<loginObjectType>({
    email: "",
    password: "",
  });
  const {
    mutate,
    error,
    isError,
    isSuccess,
    data: userData,
  } = useQueryMutationInvalidateHooksPost("api/v1/users/login");
  const dispatch = useAppDispatch();

...

  // Signin process handler
  useEffect(() => {
    console.log("hi");
    if (isSuccess) {
      if (userData) {
        dispatch(usersActions.updateUser(userData?.data?.data?.user?.name));
        dispatch(usersActions.updateToken(userData?.data?.token));
        dispatch(usersActions.updateIsLoggedIn(!!userData?.data?.token));
        alert(
          `Succeeded in login. Welcome ${userData?.data?.data?.user?.name}!`
        );
        navigate("/home");
      }
    }

    if (isError) {
      if (error instanceof AxiosError) {
        alert(error?.response?.data?.message);
      }
    }
  }, [navigate, error, isSuccess, isError, userData, dispatch]);

 //  Button functions
  const submitHandler = async (
    event: React.MouseEvent<HTMLButtonElement, MouseEvent>
  ) => {
    event.preventDefault();
    if (!loginObject?.email || !loginObject?.password) {
      alert("Please input all required fields.");
    } else if (loginObject?.email && loginObject.password) {
      //  fetching data
      const temp = {
        ...loginObject,
      };
      mutate(temp);
    }
  };

【问题讨论】:

标签: reactjs typescript redux react-hooks react-query


【解决方案1】:

我建议仅将 useEffect 钩子用于初始化而不是作为处理程序。

要对突变成功或错误做出反应,请按如下方式使用突变。

mutate(temp, {
  onSuccess: (data, variables, context) => {
    // add your success handling logic here
  },
  onError: (error, variables, context) => {
    // Add your error handling logic here
  },
  onSettled: (data, error, variables, context) => {
    // Code that must run, irrelevant of success or error, should be added here.
  },
})

通过这种方式,您将摆脱 Signin 流程处理程序 useEffect,这将删除您的循环逻辑。

【讨论】:

    猜你喜欢
    • 2021-04-10
    • 2020-08-27
    • 2020-11-16
    • 2020-06-04
    • 2021-11-01
    • 2021-09-07
    相关资源
    最近更新 更多