如何正确使用钩子?

IT技术 javascript reactjs react-native react-hooks
2021-05-04 02:08:33

我有一些问题

1- 我定义了一个从 API 获取数据并在useEffect其中调用它的函数,它运行良好但是我在 VScode 中收到了这个警告。

React Hook React.useEffect 缺少一个依赖项:'getOpenOrders'。包括它或删除依赖项数组。

2- 我在 FlatList 中实现分页,所以当用户到达数据列表的末尾时,我调用一个函数来增加当前页面,并根据当前页面更新,getOpenOrders再次获取,因为我将currentPageuseEffect传递给依赖数组

所以这里的问题是getOpenOrders应该用新数据联系以前的数据所以我使用Concat方法,

它运行良好但有一段时间我收到警告,告诉我有重复的数据,当我使用 spread [...old, new]not work 并且由于 Flatlist keyExtractor 问题或其他原因而出现大错误时,

那么这里的任何英雄都可以查看我的代码并告诉我这里有什么问题吗 1 - 2

代码片段

const OpenedAppointments = () => {

  const [openedAppointment, setOpenedAppointment] = useState([]);
  const [currentPage, setCurrentPage] = useState(1);
  const [lastPage, setLastPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const [isFetch, setIsFetch] = useState(false);




 const loadMoreOrders = () => {
    if (currentPage <= lastPage - 1) {
      setLoading(true);
      setCurrentPage((prevPage) => prevPage + 1);
      console.log('loadMore??');
    }
  };

  const _renderFooter = () => {
    return loading ? (
      <View
        style={{
          paddingVertical: 10,
        }}>
        <ActivityIndicator color="#000000" size="large" />
      </View>
    ) : null;
  };
  const getOpenOrders = () => {
    let AuthStr =
      'Bearer ,,,,';

    const headers = {
      'Content-Type': 'application/json',
      Authorization: AuthStr,
    };
    Api.post(
      `/open_orders?page=${currentPage}`,
      {},
      {
        headers,
      },
    )
      .then((res) => {
        let last_Page = res.data.open_orders.last_page;
        let allOpenedOrders = res.data.open_orders.data;
        console.log('res:', allOpenedOrders);
        console.log('last_Page', last_Page);
        setLastPage(last_Page);
        setOpenedAppointment((prevOpenedOrders) =>
          prevOpenedOrders.concat(allOpenedOrders),
        ); // issue 2

        // setOpenedAppointment((prevOpenedOrders) =>[...prevOpenedOrders, allOpenedOrders]);
        setLoading(false);

    // For pull to refresh
        setIsFetch(false);

      })
      .catch((err) => console.log('err', err));
  };
// For pull to refresh
const _refresh = () => {
    setIsFetch(true);
    getOpenOrders();
  };

  React.useEffect(() => {
    getOpenOrders();
  }, [currentPage]); // warning here "issue 1"

  return (
    <FlatList
      showsVerticalScrollIndicator={false}
      contentContainerStyle={{flexGrow: 1}}
      data={openedAppointment}
      ListEmptyComponent={renderEmpty}
      renderItem={renderItems}
      keyExtractor={(item,index) => String(index)}
      ListFooterComponent={_renderFooter}
      onEndReached={loadMoreOrders}
      onEndReachedThreshold={1}

    // For pull to refresh
      onRefresh={_refresh}
      refreshing={isFetch}
    />
  );
};

export default OpenedAppointments;
2个回答

对于问题 1:

  • 要么将依赖项添加到数组:

    React.useEffect(() => {
      getOpenOrders();
    }, [currentPage, getOpenOrders]);
    
  • 或使用@Matt Aft 回答的 eslint 规则,它不会对您的用例产生影响

对于问题 2:我建议使用 Set 删除重复项:

   setOpenedAppointment((prevOpenedOrders) =>
      Array.from(new Set([...prevOpenedOrders, ...allOpenedOrders]))
    );

这将使用价差语法 (...) 连接您的新订单和旧订单,并通过创建新集合来删除重复项。(集合只允许唯一的项目,因此会删除重复项。然后你用 Array.from 将它转换回一个数组,这样你就可以像以前一样使用它

我认为您缺少第二个数组上的扩展运算符:

setOpenedAppointment((prevOpenedOrders) =>[...prevOpenedOrders, ...allOpenedOrders]);

问题 1 也是因为react-hooks/exhaustive-deps您启用规则,基本上有两种方法可以解决此问题:

  1. 包裹getOpenOrders在 a 中useCallback并将其添加到 dep 数组中useEffect
  2. 禁用该行的 linter
 React.useEffect(() => {
   getOpenOrders();
 // eslint-disable-next-line react-hooks/exhaustive-deps
 }, [currentPage]);