简体   繁体   English

React Hook useCallback 缺少依赖项:“dir”、“order”、“page”、“perPage”和“search”

[英]React Hook useCallback has missing dependencies: 'dir', 'order', 'page', 'perPage', and 'search'

My code: looks like我的代码:看起来像

  //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]);

Here, if I add the missing dependencies and replace [searchColArr, dispatch] with [page, perPage, order, dir, searchColArr, search, dispatch] then the program runs on infinite loop on.在这里,如果我添加缺少的依赖项并将[searchColArr, dispatch]替换为[page, perPage, order, dir, searchColArr, search, dispatch]那么程序将无限循环运行。 Becasuse, on listUser action it dispatch因为,在listUser操作上它调度

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

and this USER_LIST_SUCCESS will update redux state as:这个USER_LIST_SUCCESS将更新 redux 状态为:

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

and once this meta state got updated, the page, perPage, order, dir, search will be updated as well and if I add these as dependencies, it fetchData again and while fetching data it update meta state and in this way infinite loops form.一旦这个元状态得到更新, page, perPage, order, dir, search也将被更新,如果我将这些作为依赖项添加,它会再次获取数据,在获取数据时它会更新元状态,并以这种方式形成无限循环。

What will be the best solution for this kind of situation?这种情况的最佳解决方案是什么? Or eslint-disable-line react-hooks/exhaustive-deps is the only option?或者eslint-disable-line react-hooks/exhaustive-deps是唯一的选择?

Update: listUser更新:LISTUSER

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,
    },
  });
}

Update2更新2

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

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

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

I have a solution.我有一个解决方案。 That you will not pass page, perPage, order, dir, search into listUser .您不会将page, perPage, order, dir, search传递到listUser Just pass searchCol.只需通过 searchCol。 Another param will get inside listUser .另一个参数将进入listUser You can update like this:你可以这样更新:

  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,
      })
    );
  }
};

Update : If you still want to pass others params, you can check to get data.更新:如果您仍然想传递其他参数,您可以检查以获取数据。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM