基于API获取呈现新的react组件



我正在尝试创建一个React应用程序,该应用程序将基于API响应呈现组件(获取属于它们的课程的主题标题、描述等(。其目的是能够向数据库中添加新的主题和课程,而不必向前端添加任何代码以供呈现。

import { Swiper, SwiperSlide } from 'swiper/react';                                                                                         
import Topic from './Topic.js';                                                                                                                                    
import 'swiper/swiper-bundle.min.css'                                                 
import 'swiper/swiper.min.css'                                                     

function Swiper() {                                      
return (                                      
<Swiper                                          
spaceBetween={50}                                
slidesPerView={1}                                 
loop={true}                                
direction={'horizontal'}                                
>                                                  
<SwiperSlide><Topic /></SwiperSlide>                                
</Swiper>                                
);                                
};                                

export default Swiper;   

我有一个Swiper组件,我将在其中获取所有主题的列表,并根据响应用幻灯片填充滑动器。

我遇到的问题是,对于每个主题,在点击事件中,它需要:

  • 打开一个新页面并发出第二个API请求,列出该主题中的所有课程以填充该页面。然而,这需要我手动为每个主题创建一个新页面,并且我正在努力减少在前端更新代码的必要性。

  • 或者我可以把滑动器组件换成显示课程的组件。然而,这种方法我需要发出第二个api请求,然后将数据传递给主应用程序组件,以便它可以用新组件替换Swiper。我不知道该怎么办。

如果我对如何实现这一目标有任何想法,或者我对如何做到这一点的假设是否准确,我将不胜感激。

谢谢。

如果能提供任何关于如何实现这一目标的想法,或者我对如何实现这目标的假设是否准确,我们将不胜感激。

所以这可能不是实现您想要的东西的最佳方式,但以下是我将如何处理它…

打开一个新页面,并发出第二个API请求,列出该主题中的所有课程,以填充该页面。然而,这需要我手动为每个主题创建一个新页面,并且我正在努力减少在前端更新代码的必要性。

我会用一个动态路由来做这件事,并使用类似react router的东西来添加一个链接,如下所示:

<Link to={`/topic/${topic.name`}>
{topic.name}
</Link>

然后用这样的东西在我的应用程序中捕捉这条路线:

<Route path="/topic/:topicName" element={<Topic />}/>

现在,我需要创建我的主题页面,并确保在呈现该组件中的任何内容之前,先获取有关该主题的其他详细信息,类似于我下面所说的内容可能会给你一个想法。还可以看看useParams是如何用于将topicName从url路径中拉出的:

const Topic = () => {
const [loading, setLoading] = useState(true);

const { topicName } = useParams();
const [topic, setTopic] = useState(null);
useEffect(() => {
/**
Add API Code here to fetch the topic, and when you get a response call
setTopic(response.data) or something similar to set it locally.
Also make sure you call setLoading(false);
*/
}, []);
if(loading){
return (
<h1>Loading Topic...</h1>
)
}
if(topic){
return (
<div>
<h1>{topic.name}</h1>
</div>
);
}
return null;
}

希望这能让你知道如何做这样的事情,如果你想得到更多的澄清,请告诉我。

我也有和你一样的东西,Swiper要求一个独特的"键";对于每个物体,但我很确定我从地图API收集的博物馆应该有一个UID每个

import { View, Text, Button, TouchableOpacity, Image } from "react-native";
import React, { useLayoutEffect, useRef, useState, useEffect } from "react";
import { useNavigation } from "@react-navigation/native";
import useAuth from "../hooks/useAuth";
import { SafeAreaView } from "react-native-safe-area-context";
import { useTailwind } from "tailwind-rn";
import { Ionicons } from "@expo/vector-icons";
import Swiper from "react-native-deck-swiper";
import * as Location from "expo-location";
import * as Permissions from "expo-permissions";
import { serverTimestamp, setDoc, doc } from "firebase/firestore";
import { GOOGLE_MAPS_APIKEY } from "@env";

const HomeScreen = () => {
const navigation = useNavigation();
const { user, logout } = useAuth();
const tailwind = useTailwind();
const swipeRef = useRef(null);
const [location, setLocation] = useState(null);
const [errorMsg, setErrorMsg] = useState(null);
const [data, setData] = useState([]);
useEffect(() => {
(async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== "granted") {
setErrorMsg("Permission to access location was denied");
return;
}
let location = await Location.getCurrentPositionAsync({});
setLocation(location);
const url =
"https://maps.googleapis.com/maps/api/place/nearbysearch/json?";
const location2 = `location=${location.coords.latitude},${location.coords.longitude}`;
const radius = "&radius=2000";
const type = "&keyword=museum";
const key = "&key=GOOGLE_MAPS_APIKEY";
const restaurantSearchUrl = url + location2 + radius + type + key;
const fetchData = async () => {
try {
const response = await fetch(restaurantSearchUrl);
const json = await response.json();
console.log(json.results);
setData(json.results);
} catch (error) {
console.log("error", error);
}
};
fetchData();
/* catch the error here */
})();
}, []);
return (
<SafeAreaView style={tailwind("flex-1")}>
{/*Header */}
<View style={tailwind("flex-row items-center justify-between px-5")}>
<TouchableOpacity onPress={logout}>
<Image
style={tailwind("h-10 w-10 rounded-full")}
source={{ uri: user.photoURL }}
/>
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.navigate("Modal")}>
<Image
style={tailwind("h-14 w-14")}
source={require("../logo.png")}
/>
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.navigate("DummyHome")}>
<Ionicons name="chatbubbles-sharp" size={30} />
</TouchableOpacity>
</View>
{/*End of Header */}
{/*Card */}
<View style={tailwind("flex-1 mt-0.5")}>
<Swiper
ref={swipeRef}
containerStyle={{ backgroundColor: "transparent" }}
cards={DUMMY_DATA}
stackSize={5}
cardIndex={0}
verticalSwipe={false}
animateCardOpacity
onSwipedLeft={() => {
console.log("Nay");
}}
onSwipedRight={() => {
console.log("Yay");
}}
overlayLabels={{
left: {
title: "NAY",
style: {
label: {
textAlign: "right",
color: "red", //make it purple
},
},
},
right: {
title: "YAY",
style: {
label: {
color: "purple",
},
},
},
}}
renderCard={(card) =>
card ? (
<View
key={card.id}
style={tailwind("relative bg-white-500 h-3/4 rounded-2xl")}
>
<Image
style={tailwind("absolute top-0 h-full w-full rounded-xl")}
source={{ uri: card.photoURL }}
/>
<View
style={tailwind(
"absolute bottom-0 bg-white w-full flex-row justify-between items-between h-20 px-6 py-2 rounded-b-xl"
)}
>
<View>
<Text style={tailwind("text-xl font-bold")}>
{card.name}
</Text>
</View>
<Text style={tailwind("text-2xl font-bold")}>
{card.address}
</Text>
</View>
</View>
) : (
<Text>ENDDDDddd</Text>
)
}
/>
</View>
<Button title="Places" onPress={() => this.handleRestaurantSearch()} />
</SafeAreaView>
);
};
export default HomeScreen;

最新更新