我想在 ReactNative FlatList 中呈现项目列表,最初我加载 15 个项目,然后在用户向下滚动时加载更多项目。我正在使用 FlatList 的onEndReached
道具来获取滚动的新项目。我正在使用一个带有 POST 方法的 api,该方法将一个包含 pageNumber、pageSize 等的对象作为输入并返回一个{ success: true, message: 'success.', data: [ items : [...] ] }
包含列表项的对象。
为了实现这一点,我使用了 apisauce npm 包并编写了一个自定义钩子(useSearch.js)来处理形成 api 请求对象,然后调用 api 并获取项目。
当我向下滚动到屏幕时出现以下错误。当组件第一次加载时,我没有收到任何错误,但是当我滚动时,我遇到了错误。尝试了一段时间后,我意识到相同的代码适用于任何其他 Http GET 请求,但是当我使用 Http POST 方法时它不起作用。如何解决这个问题呢。任何帮助表示赞赏。
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s, a useEffect cleanup function,
in App (created by ExpoRoot)
in RCTView (at NativeAppearance.tsx:4)
in FallbackAppearanceProvider (at src/index.tsx:70)
in AppearanceProvider (created by ExpoRoot)
in RootErrorBoundary (created by ExpoRoot)
in ExpoRoot (at renderApplication.js:45)
in RCTView (at AppContainer.js:109)
in RCTView (at AppContainer.js:135)
in AppContainer (at renderApplication.js:39)
TypeError: undefined is not an object (evaluating 'item.listingId.toString')
下面是我正在使用的代码
客户端.js
import { create } from "apisauce";
const apiClient = create({
baseURL: 'http://localhost:9000',
});
export default apiClient;
useSearch.js(自定义挂钩)
const useSearch = () => {
const searchList = { pageNumber: 1, pageSize: 15, sortField: "createddate", sortOrder: "desc", isActive: true};
const [items, setItems] = useState([]);
const [error, setError] = useState(false);
const [pageNumber, setPageNumber] = useState(1);
const [loading, setLoading] = useState(false);
const endpoint = "/listings";
const getItems = async (categoryId) => {
setLoading(true);
setPageNumber((prevPageNumber) => prevPageNumber + 1);
const response = await apiClient.post(`${endpoint}/search`, {
...searchList,
pageNumber,
categoryId,
});
setLoading(false);
if (!response.ok) {
if (response.data && response.data.message) return setError(true);
else return setError(true);
}
if (items && items.length > 0)
setItems([...items, response.data?.data?.items]);
else setItems(response.data?.data?.items);
return response;
};
return {error, getItems, items, loading };
};
ListingsScreen.js(组件)
const ListingsScreen = ({ route }) => {
const categoryId = route.params;
const { items, getItems, loading } = useSearch();
useEffect(() => {
getItems(categoryId);
}, []);
return (
<>
<ActivityIndicator visible={loading} />
<Screen style={styles.screen}>
<FlatList
showsVerticalScrollIndicator={false}
data={items}
keyExtractor={(item) => item.listingId.toString()}
renderItem={({ item }) => (
<CustomListItem onPress={() => console.log("On Press Item")} title={item.name} subTitle={item.category} />
)}
onEndReached={() => getItems(categoryId)}
onEndReachedThreshold={0.5}
/>
</Screen>
</>
);
};