我有一个主屏幕,其中有一个平面列表来显示图像和电影标题( Package 在一个盒子组件中),当点击该组件时会被定向到MovieDetail Screen,在电影细节中有类似的电影部分,这部类似的电影使用了和主屏上一样的方式来显示电影,当我在电影推荐部分按下其中一部电影时,电影详细信息屏幕的内容不会根据我按下的电影而改变,如何使它在我按下类似电影部分(在电影详细信息上)中的一部电影时改变电影详细信息屏幕的内容?
这是我的主屏幕
class Home extends Component {
constructor(props) {
super(props);
this.state = {
dataCSoon: [],
isContentLoading: false
isFetching: false,
};
}
getComingSoon = () => {
fetch(
'https://api.themoviedb.org/3/movie/upcoming?api_key=<The API Key Here>'
)
.then((response) => response.json())
.then((json) =>
this.setState({
dataCSoon: json.results,
})
)
.catch((error) => console.error(error))
.finally(() =>
this.setState({
isContentLoading: false,
isFetching: false,
})
);
};
componentDidMount = () => {
this.getComingSoon();
};
renderItem = ({ item }) => {
const { navigation } = this.props;
return (
<>
<Pressable
onPress={() =>
navigation.navigate('Detail Film', {
data: item.id,
title: item.title,
})
}>
<Box alignItems="center">
<Box
maxW="150"
h="260"
rounded="lg"
overflow="hidden"
borderWidth="1"
borderColor="coolGray.600"
backgroundColor="gray.700"
shadow="2"
m="2">
<Box>
<AspectRatio w="100%" ratio={16 / 9}>
<Image
source={{
uri: 'https://image.tmdb.org/t/p/w500/' + item.poster_path,
}}
alt="image"
h="200"
w="100%"
/>
</AspectRatio>
<Center
backgroundColor="rgba(52, 52, 52, 0Bu.7)"
position="absolute"
mt="176"
h="6"
w="20"
roundedTopRight="10"
roundedBottomRight="10">
<HStack>
<Icon
size="5"
color="#FF8700"
as={<Ionicons name="star-outline" />}
/>
<Text color="#FF8700" fontWeight="700" fontSize="14" ml="2">
{item.vote_average}
</Text>
</HStack>
</Center>
</Box>
<Stack p="4" space={3} mt="110">
<Stack space={2}>
<Heading fontSize="15" ml="-1" noOfLine="3" color="#fff">
{item.title}
</Heading>
</Stack>
</Stack>
</Box>
</Box>
</Pressable>
</>
);
};
render() {
const {
dataCSoon
} = this.state;
const { navigation } = this.props;
return (
<ScrollView>
<Box bgColor="#242A32" h="100%" pl="5" mb="5">
<Text color="#FFFFFF" mt="10" fontWeight="bold" fontSize="20">
Welcome
</Text>
<Text color="#FFFFFF" fontWeight="semibold" fontSize="15">
Choose Movie To View
</Text>
<View justifyContent="center">
<HStack my="4" space={145} w="100%" mt="5">
<Text color="#ffffff" fontSize="18">
Coming Soon
</Text>
<Pressable
onPress={() =>
navigation.navigate('More', { data: dataCSoon })
}>
<Text color="#0296E5" fontSize="15" mr="8" fontWeight="bold">
See More
</Text>
</Pressable>
</HStack>
<FlatList
mt="-2"
horizontal
data={ dataCSoon.slice(0, 4)}
keyExtractor={(item) => item.id}
renderItem={this.renderItem}
onRefresh={() => this.onRefresh()}
refreshing={this.state.isFetching}
/>
</View>
</Box>
</ScrollView>
);
}
}
export default Home;
这是电影细节屏幕
class MovieDetail extends Component {
constructor(props) {
super(props);
this.state = {
dataId: this.props.route.params.data,
content: [],
contentGenre: [],
similar: [],
isContentLoading: true,
};
}
getContent = (movie_id) => {
fetch(
`https://api.themoviedb.org/3/movie/${movie_id}?api_key=<The API Key>`
)
.then((response) => response.json())
.then((json) =>
this.setState({
content: json,
})
)
.catch((error) => console.error(error))
.finally(() =>
this.setState({
isContentLoading: false,
isFetching: false,
})
);
};
getDetails = (movie_id) => {
fetch(
`https://api.themoviedb.org/3/movie/${movie_id}?api_key=<The API Key>`
)
.then((response) => response.json())
.then((json) =>
this.setState({
contentGenre: json.genres[0].name,
activeContent: json.id,
})
)
.then(() => this.fetchContent(this.state.activeContent))
.catch((error) => console.error(error))
.finally(() =>
this.setState({
isCategoriesLoading: false,
})
);
};
getSimilar = (movie_id) => {
fetch(
`https://api.themoviedb.org/3/movie/${movie_id}/similar?api_key=<The API Key>`
)
.then((response) => response.json())
.then((json) => this.setState({ similar: json.results }))
.catch((error) => console.error(error))
.finally(() =>
this.setState({
isContentLoading: false,
isFetching: false,
})
);
};
componentDidMount = () => {
const { dataId } = this.state;
this.getContent(dataId);
this.getDetails(dataId);
this.getSimilar(dataId);
};
renderItem = ({ item }) => {
const { navigation } = this.props;
return (
<>
<Pressable
onPress={() =>
navigation.navigate('Detail Film', {
data: item.id,
title: item.title,
})
}>
<Box alignItems="center">
<Box
maxW="150"
h="260"
rounded="lg"
overflow="hidden"
borderWidth="1"
borderColor="coolGray.600"
backgroundColor="gray.700"
shadow="2"
m="2">
<Box>
<AspectRatio w="100%" ratio={16 / 9}>
<Image
source={{
uri:
'https://image.tmdb.org/t/p/w500/' + item.poster_path,
}}
alt="image"
h="200"
w="100%"
/>
</AspectRatio>
<Center
backgroundColor="rgba(52, 52, 52, 0.7)"
position="absolute"
mt="176"
h="6"
w="20"
roundedTopRight="10"
roundedBottomRight="10">
<HStack>
<Icon
size="5"
color="#FF8700"
as={<Ionicons name="star-outline" />}
/>
<Text color="#FF8700" fontWeight="700" fontSize="14" ml="2">
{item.vote_average.toFixed(1)}
</Text>
</HStack>
</Center>
</Box>
<Stack p="4" space={3} mt="110">
<Stack space={2}>
<Heading fontSize="15" ml="-1" noOfLine="3" color="#fff">
{item.title}
</Heading>
</Stack>
</Stack>
</Box>
</Box>
</Pressable>
</>
);
};
render() {
const {
contentGenre,
content,
isContentLoading
similar,
} = this.state;
return isContentLoading ? (
<Spinner color="indigo.500" size="lg" mt="100%" />
) : (
<ScrollView h="100%">
<Box bgColor="#242A32" h="100%" pb="50">
<Image
source={{
uri: 'https://image.tmdb.org/t/p/w500/' + content.backdrop_path,
}}
w="100%"
h="250"
resizeMode="contain"
opacity="0.6"
borderBottomLeftRadius="20"
borderBottomRightRadius="20"
/>
<Image
source={{
uri: 'https://image.tmdb.org/t/p/w500/' + content.poster_path,
}}
w="30%"
h="150"
ml="5"
mt="-25%"
resizeMode="contain"
rounded="25"
/>
<View flexDirection="column" ml="4" mr="4">
<Text
color="#ffffff"
fontSize="18"
fontWeight="bold"
ml="38%"
mt="-17%"
w="60%"
noOfLine="2">
{content.title}
</Text>
<HStack mt="10" justifyContent="center">
<Text color="#ffffff" fontSize="14">
{content.id}
</Text>
<Divider
bg="#3A3F47"
thickness="3"
mx="2"
orientation="vertical"
/>
<Text color="#fff" fontSize="16" mt="4">
Similar
</Text>
<Divider
bg="#3A3F4F"
thickness="3"
w="20%"
orientation="horizontal"
/>
<FlatList
mt="2"
horizontal
data={similar}
keyExtractor={(item) => item.id}
renderItem={this.renderItem}
/>
</VStack>
</View>
</Box>
</ScrollView>
);
}
}
export default MovieDetail;
在主屏幕和电影细节屏幕上,有一个renderItem函数用于显示电影细节,当按下这两个函数时,将进入电影细节屏幕。
2条答案
按热度按时间k97glaaz1#
在
MovieDetail
屏幕中,您不需要导航,因为您不想更改当前屏幕。要保持相同的逻辑并更新导航参数,请将与
请注意,您需要更新数据。我认为您可能需要添加一个
componentDidUpdate
函数来完成此操作。我现在不再熟悉它,因为我将使用useEffect
以函数的方式完成此操作。5n0oy7gb2#
如果我没理解错你的问题的话,简单的解决办法应该是这样的。
1.将电影ID从主页传递到电影详细信息屏幕。
1.将此ID设置为MovieDetail屏幕中的默认状态。
1.您可以在componentDidMount中获取电影细节。
1.您无需在MovieDetail屏幕中重新导航,当您单击某个电影时,只需设置新的movieId状态并检查componentDidUpdate中moveId的状态
顺便说一句如果你使用reactnavigation当你在params中传递变量时要小心.更多信息