【问题标题】:useEffect is on a infinity loop even with an empty dependency arrayuseEffect 处于无限循环中,即使依赖项数组为空
【发布时间】:2022-09-24 22:55:01
【问题描述】:

我使用我的 useEffect 调度一个函数来在页面安装时填充我的状态。 useEffect 处于无限循环中,即使我放置了一个空的依赖数组。

const token = JSON.parse(localStorage.getItem(\"xibo\"));
  const access_token = token.access_token;

  useEffect(() => {
    
      dispatch(getDisplays(access_token));
      
  }, []);

我已经尝试放置一些依赖项,但结果相同。

const token = JSON.parse(localStorage.getItem(\"xibo\"));
  const access_token = token.access_token;

  useEffect(() => {
    
      dispatch(getDisplays(access_token));
    
  }, [access_token, dispatch]);

知道如何解决这个问题吗?

这是文件的完整代码

import React, { useEffect } from \"react\";
import { WaveLoading } from \"react-loadingg\";
import { useDispatch, useSelector } from \"react-redux\";
import { getDisplays } from \"../features/xiboAuth/xiboSlice\";

const DisplayList = () => {
  const dispatch = useDispatch();
  const { isLoading } = useSelector((store) => store.xibo);

  const token = JSON.parse(localStorage.getItem(\"xibo\"));
  const access_token = token.access_token;

  useEffect(() => {
    dispatch(getDisplays(access_token));
  }, [access_token, dispatch]);

  return (
    <>
      {isLoading ? (
        <WaveLoading />
      ) : (
        <div className=\"container-fluid\">
          <div className=\"title_table\">
            <h3>List of displays</h3>
          </div>
          <table className=\"table table-striped\">
            <thead>
              <tr>
                <th className=\"col\">#</th>
                <th className=\"col\">name</th>
                <th className=\"col\">type</th>
                <th className=\"col\">ip</th>
              </tr>
            </thead>
            <tbody>
              <tr></tr>
            </tbody>
          </table>
        </div>
      )}
    </>
  );
};

export default DisplayList;

这是调用此组件的文件

import React, { useEffect } from \"react\";
import { WaveLoading } from \"react-loadingg\";
import { useDispatch, useSelector } from \"react-redux\";
import { toast } from \"react-toastify\";
import DisplayList from \"../components/DisplayList\";
import { getDisplays, getToken } from \"../features/xiboAuth/xiboSlice\";

const Dashboard = () => {
  const { user } = useSelector((store) => store.auth);
  const { isError, message, isLoading, xibo } = useSelector(
    (store) => store.xibo,
  );

  const dispatch = useDispatch();

  useEffect(() => {
    if (isError) {
      toast.error(message);
    }
    if (user) {
      dispatch(getToken());
    }
  }, [user, isError, message, dispatch]);


  return (
    <>
      {isLoading ? (
        <WaveLoading />
      ) : (
        <div className=\"col py-3\">
          <div className=\"d-flex dash_dsp_list\">
            <DisplayList />
          </div>
        </div>
      )}
    </>
  );
};

export default Dashboard;

这是 useEffect 只能调用一次的 reducer。

  import { createSlice, createAsyncThunk } from \"@reduxjs/toolkit\";
  import xiboService from \"./xiboService.js\";

  const data = JSON.parse(localStorage.getItem(\"xibo\"));

  const initialState = {
    xibo: data ? data : null,
    displays: null,
    isError: false,
    isLoading: false,
    isSuccess: false,
    message: \"\",
  };

  export const getToken = createAsyncThunk(\"xibo/getToken\", async (thunkAPI) => {
    try {
      const response = await xiboService.getAccessToken();

      if (response.data.status === 201) {
        localStorage.setItem(\"xibo\", JSON.stringify(response.data.data));
      }

      return response;
    } catch (error) {
      const message =
        (error.response && error.response.data && error.response.data.message) ||
        error.message ||
        error.toString();

      return thunkAPI.rejectWithValue(message);
    }
  });

  export const getDisplays = createAsyncThunk(
    \"xibo/getDisplays\",
    async (data, thunkAPI) => {
      try {
        return await xiboService.getDisplayList(data);
      } catch (error) {
        const message =
          (error.response &&
            error.response.data &&
            error.response.data.message) ||
          error.message ||
          error.toString();

        return thunkAPI.rejectWithValue(message);
      }
    },
  );

  export const xiboSlice = createSlice({
    name: \"xibo\",
    initialState,
    reducers: {
      reset: (state) => {
        state.isError = false;
        state.isSuccess = false;
        state.isLoading = false;
        state.message = \"\";
      },
    },
    extraReducers: (builder) => {
      builder
        .addCase(getToken.pending, (state) => {
          state.isLoading = true;
        })
        .addCase(getToken.fulfilled, (state, action) => {
          state.isLoading = false;
          state.isSuccess = true;
          state.xibo = action.payload;
        })
        .addCase(getToken.rejected, (state, action) => {
          state.isLoading = false;
          state.isError = true;
          state.message = action.payload;
          state.xibo = null;
        })
        .addCase(getDisplays.pending, (state) => {
          state.isLoading = true;
        })
        .addCase(getDisplays.fulfilled, (state, action) => {
          state.isLoading = false;
          state.isSuccess = true;
          state.displays = action.payload;
        })
        .addCase(getDisplays.rejected, (state, action) => {
          state.isLoading = false;
          state.isError = true;
          state.message = action.payload;
          state.displays = null;
        });
    },
  });

  export const { reset } = xiboSlice.actions;
  export default xiboSlice.reducer;

    标签: reactjs react-redux use-effect redux-toolkit


    【解决方案1】:

    在您的第一个示例中,您说您的 useEffect 会重复触发,即使依赖项数组为空。这意味着您的DisplayList 组件正在不断地重新创建。显然问题出在您的Dashboard 组件中,它必须是useEffect 中的某些内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-25
      • 2020-11-02
      • 2021-09-27
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      • 2021-01-08
      相关资源
      最近更新 更多