【问题标题】:React Hook useCallback has missing dependencies: 'dir', 'order', 'page', 'perPage', and 'search'React Hook useCallback 缺少依赖项:'dir'、'order'、'page'、'perPage' 和 'search'
【发布时间】:2021-06-21 15:52:08
【问题描述】:

我的代码:看起来像

  //GLOBAL STATE INITIALIZATION
  const page = useSelector((state) => state.users.meta.page);
  const perPage = useSelector((state) => state.users.meta.perPage);
  const order = useSelector((state) => state.users.meta.order);
  const dir = useSelector((state) => state.users.meta.dir);
  const search = useSelector((state) => state.users.meta.search);

  // FUNCTIONS
  const fetchData = useCallback(
    (
      pageNumber = page,
      pageSize = perPage,
      columnOrder = order,
      colDir = dir,
      query = search
    ) => {
      dispatch(
        listUser(pageNumber, pageSize, columnOrder, colDir, searchColArr, query)
      );
    },
    [searchColArr, dispatch]
  );
  //throwing warning above for missing dependencies


  useEffect(() => {
    dispatch(resetState(function () {}));
    fetchData();
  }, [dispatch, fetchData]);

在这里,如果我添加缺少的依赖项并将[searchColArr, dispatch] 替换为[page, perPage, order, dir, searchColArr, search, dispatch],那么程序将在无限循环上运行。因为,它会在 listUser 操作上调度

dispatch(
  userActions.USER_LIST_SUCCESS({
    list: data.data,
    meta: data.meta,
  })
);

而这个USER_LIST_SUCCESS 会将redux 状态更新为:

USER_LIST_SUCCESS: (state, action) => {
  state.list = action.payload.list;
  state.meta = action.payload.meta;
  state.isLoading = false;
},

一旦这个元状态被更新,page, perPage, order, dir, search 也将被更新,如果我将它们添加为依赖项,它会再次 fetchData 并在获取数据时更新元状态并以这种方式形成无限循环。

这种情况的最佳解决方案是什么?还是eslint-disable-line react-hooks/exhaustive-deps 是唯一的选择?

更新: 列表用户

import user from "../../services/userService";
export const listUser =
  (page, perPage, order, dir, searchCol, search) => async (dispatch) => {
  try {
    dispatch(
      userActions.SET_IS_LOADING({
        isLoading: true,
      })
    );
    const { data } = await user.listUser(
      page,
      perPage,
      order,
      dir,
      searchCol,
      search
    );
    dispatch(
      userActions.USER_LIST_SUCCESS({
        list: data.data,
        meta: data.meta,
      })
    );
  } catch (error) {
    toastify.error(error.response.data.message);
    dispatch(
      userActions.USER_LIST_FAIL({
        errors:
          error.response && error.response.data.errors
            ? error.response.data.errors
            : error.response.data,
      })
    );
  }
};

user.listUser

export async function listUser(
  page,
  perPage,
  order,
  dir,
  searchColArr,
  search
) {
  let searchCol = JSON.stringify(searchColArr);
  return httpClient.get(apiEndpoint, {
    params: {
      page,
      perPage,
      order,
      dir,
      searchCol,
      search,
    },
  });
}

更新2

const handlePageChange = (pageNumber) => {
  fetchData(pageNumber);
};

const handlePageLengthChange = (pageSize) => {
  fetchData(null, pageSize);
};

const handleSort = (newOrder, newDir) => {
  fetchData(null, null, newOrder, newDir);
};

【问题讨论】:

  • 你能详细说明一下listUser函数吗
  • 我已经更新了,请你看看告诉我。
  • 任何帮助.......

标签: reactjs


【解决方案1】:

我有一个解决方案。你不会将page, perPage, order, dir, search 传递给listUser。只需通过 searchCol。另一个参数将进入listUser。你可以这样更新:

  const fetchData = useCallback(() => {
    dispatch(listUser(searchColArr));
  }, [searchColArr, dispatch])

export const listUser =
  ( searchCol ) => async (dispatch, getState) => {
  try {
    dispatch(
      userActions.SET_IS_LOADING({
        isLoading: true,
      })
    );
    const page = getState((state) => state.users.meta.page);
    const perPage = getState((state) => state.users.meta.perPage);
    const order = getState((state) => state.users.meta.order);
    const dir = getState((state) => state.users.meta.dir);
    const search = getState((state) => state.users.meta.search);
    const { data } = await user.listUser(
      page,
      perPage,
      order,
      dir,
      searchCol,
      search
    );
    dispatch(
      userActions.USER_LIST_SUCCESS({
        list: data.data,
        meta: data.meta,
      })
    );
  } catch (error) {
    toastify.error(error.response.data.message);
    dispatch(
      userActions.USER_LIST_FAIL({
        errors:
          error.response && error.response.data.errors
            ? error.response.data.errors
            : error.response.data,
      })
    );
  }
};

更新:如果你还想传递其他参数,你可以检查获取数据。

listUser = (page, perPage, order, dir, searchCol, search) => async (dispatch, getState) => {
  const page = page || getState((state) => state.users.meta.page);
  ...
};

【讨论】:

  • 它看起来是一种解决方案,但它可能不适合我的情况,正如您在更新的部分中看到的那样,我可能会在不同的情况下通过 page, perPage, order, size。因此,我不能完全删除这些参数并直接在每个案例的操作中检索它们。
  • 你能告诉我如何导入或定义getState ,因为目前,它的显示没有定义。
猜你喜欢
  • 1970-01-01
  • 2021-06-17
  • 2023-02-21
  • 2022-07-04
  • 1970-01-01
  • 2019-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多