簡體   English   中英

如何正確使用鈎子?

[英]How to use hooks in correct way?

我有一些問題

1- 我定義了一個從 API 獲取數據並在useEffect調用它的useEffect ,它運行良好但是我在 VScode 中收到了這個警告。

React Hook React.useEffect 缺少一個依賴項:'getOpenOrders'。 包括它或刪除依賴項數組。

2-我在FlatList中實現分頁,所以當用戶到達數據列表的末尾時,我調用一個函數來增加當前頁面,並根據當前頁面更新,再次獲取getOpenOrders ,因為我將currentPage傳遞給useEffect到依賴數組

所以這里的問題是getOpenOrders應該用新數據聯系以前的數據,所以我使用Concat方法,

它運行良好但有一段時間我收到警告,告訴我有重復的數據,當我使用 spread [...old, new] ,我遇到了一個大錯誤,因為 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;

對於問題 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. 包裹getOpenOrdersuseCallback並將其在添加到DEP陣列useEffect
  2. 禁用該行的 linter
 React.useEffect(() => {
   getOpenOrders();
 // eslint-disable-next-line react-hooks/exhaustive-deps
 }, [currentPage]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM