经过2天的研究,希望我能在这里找到答案!
我正在调用API来检索电影列表。电影将显示在称为“新电影”的视图中
在此视图中,我有两种可能性:将电影设为收藏夹(通过单击“心脏”图标),然后单击蓝色按钮,上面写着“我看过这部电影”
为此,我正在使用react-redux。 直到现在,当我把电影放到最喜欢的地方时,它仍然有效。状态发生变化(请参见mapStateToProps()函数),我通过单击下面导航栏的选项卡来检索这部电影(请参见附件)
现在,当我单击“我看过这部电影”按钮时,我正在尝试在同一类“ FilmDetail”上进行近似相同的操作,只是电影将改为显示在“已查看”标签中(请参见附件)
所以我的问题是如何在同一类中创建另一个mapStateToProps()来更改状态并使影片显示在“已看到”标签中?
我试图在componentDidMount()函数中执行操作,但是它不起作用。 也许有一个我不知道的react-redux概念。
这是完整的代码(适用于“收藏夹”页面)
import React from 'react'
import { StyleSheet, Share, Platform, View, Text, ActivityIndicator, ScrollView, Image,
TouchableOpacity, Button } from 'react-native'
import { getFilmDetailFromApi, getImageFromApi } from '../API/TMDBApi'
import moment from 'moment'
import numeral from 'numeral'
import {connect} from 'react-redux'
import EnlargeShrink from'../Animations/EnlargeShrink'
import { NativeModules } from 'react-native'
if (__DEV__) {
NativeModules.DevSettings.setIsDebuggingRemotely(true)
}
class FilmDetail extends React.Component {
static navigationOptions= ({ navigation }) => {
const { params } = navigation.state
// On accède à la fonction shareFilm et au film via les paramètres qu'on a ajouté à la navigation
if (params.film != undefined && Platform.OS === 'ios') {
return {
// On a besoin d'afficher une image, il faut donc passe par une Touchable une fois de plus
headerRight: <TouchableOpacity
style={styles.share_touchable_headerrightbutton}
onPress={() => params.shareFilm()}>
<Image
style={styles.share_image}
source={require('../Images/ic_share.png')} />
</TouchableOpacity>
}
}
}
constructor (props){
super (props)
this.state={
film: undefined,
isLoading: false
}
this._shareFilm = this._shareFilm.bind(this)
}
_updateNavigationParams() {
this.props.navigation.setParams({
shareFilm: this._shareFilm,
film: this.state.film
})
}
componentDidMount() {
const favoriteFilmIndex = this.props.favoritesFilm.findIndex(item => item.id === this.props.navigation.state.params.idFilm)
if (favoriteFilmIndex !== -1) { // Film déjà dans nos favoris, on a déjà son détail
// Pas besoin d'appeler l'API ici, on ajoute le détail stocké dans notre state global au state de notre component
this.setState({
film: this.props.favoritesFilm[favoriteFilmIndex]
}, () => { this._updateNavigationParams() })
return
}
// Le film n'est pas dans nos favoris, on n'a pas son détail
// On appelle l'API pour récupérer son détail
this.setState({ isLoading: true })
getFilmDetailFromApi(this.props.navigation.state.params.idFilm).then(data => {
this.setState({
film: data,
isLoading: false
}, () => { this._updateNavigationParams()})
})}
_shareFilm(){
const { film } = this.state
Share.share({ title: film.title, message: film.overview })
}
_displayFloatingActionButton(){
const { film } = this.state
if ( film != undefined && Platform.OS === 'android') {
return (
<TouchableOpacity
style={styles.share_touchable_floatingactionbutton}
onPress={() => this._shareFilm()}>
<Image
style={styles.share_image}
source={require('../Images/ic_share.png')} />
</TouchableOpacity>
)
}
}
_displayLoading(){
if (this.state.isLoading){
return(
<View style={styles.Loading_container}>
<ActivityIndicator size='large'/>
</View>
)
}
}
_toggleFavorite() {
const action = { type: "TOGGLE_FAVORITE", value: this.state.film }
this.props.dispatch(action)
}
componentDidUpdate() {
console.log(this.props.favoritesFilm);
}
_displayFavoriteImage() {
var sourceImage = require('../Images/ic_favorite_border.png')
var shouldEnlarge= false //si le film n'est pas en favoris on veut qu'au en clic sur le button, celui-ci s'agrandise => shouldEnlarge a true!
if (this.props.favoritesFilm.findIndex (item => item.id === this.state.film.id) !== -1)
{
// Film dans nos favoris
sourceImage = require('../Images/ic_favorite.png')
shouldEnlarge= true
}
return (
<EnlargeShrink
shouldEnlarge= {shouldEnlarge}>
<Image
style={styles.favorite_image}
source={sourceImage}
/>
</EnlargeShrink>
)
}
_displayFilm(){
const {film}= this.state
if(film != undefined) {
return(
<ScrollView style={styles.scrollview_container}>
<Image
style={styles.image}
source={{uri: getImageFromApi(film.backdrop_path)}}
/>
<Text style={styles.title_text}>{film.title}</Text>
<TouchableOpacity
style={styles.favorite_container}
onPress={() => this._toggleFavorite()}>
{this._displayFavoriteImage()}
</TouchableOpacity>
<Text style={styles.description_text}>{film.overview}</Text>
<Text style={styles.default_text}>Sorti le {moment(new Date(film.release_date)).format('DD/MM/YYYY')}</Text>
<Text style={styles.default_text}>Note : {film.vote_average} / 10</Text>
<Text style={styles.default_text}>Nombre de votes : {film.vote_count}</Text>
<Text style={styles.default_text}>Budget : {numeral(film.budget).format('0,0[.]00 $')}</Text>
<Text style={styles.default_text}>Genre(s) : {film.genres.map(function(genre){
return genre.name;
}).join(" / ")}
</Text>
<Text style={styles.default_text}>Companie(s) : {film.production_companies.map(function(company){
return company.name;
}).join(" / ")}
</Text>
</ScrollView>
)
}
}
state={
toggle: false
}
_toggleVus(){
const newState = !this.state.toggle;
this.setState({toggle:newState})
}
render() {
const {toggle} = this.state;
const textValue= toggle?"Non vu":"Marquer comme vu";
console.log(this.props);
return (
<View style={styles.main_container}>
{this._displayFilm()}
{this._displayLoading()}
{this._displayFloatingActionButton()}
<View >
<TouchableOpacity style={styles.Buttom}
onPress={() =>this._toggleVus()}>
<Text style={styles.text}>{textValue}</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
main_container: {
flex: 1,
},
Loading_container:{
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
},
scrollview_container:{
flex: 1,
},
image: {
height: 169,
margin: 5
},
title_text: {
fontWeight: 'bold',
fontSize: 35,
flex: 1,
flexWrap: 'wrap',
marginLeft: 5,
marginRight: 5,
marginTop: 10,
marginBottom: 10,
color: '#000000',
textAlign: 'center'
},
description_text: {
fontStyle: 'italic',
color: '#666666',
margin: 5,
marginBottom: 15
},
default_text: {
marginLeft: 5,
marginRight: 5,
marginTop: 5,
},
favorite_container:{
alignItems: 'center'
},
favorite_image:{
flex: 1,
width: null,
height: null
},
share_touchable_floatingactionbutton:{
position: 'absolute',
width: 60,
height: 60,
right: 30,
bottom: 30,
borderRadius: 30,
backgroundColor: '#e91e63',
justifyContent: 'center',
alignItems: 'center'
},
share_image:{
width: 30,
height: 30
},
share_touchable_headerrightbutton: {
marginRight: 8
},
Buttom:{
backgroundColor:'dodgerblue',
justifyContent:'center'
},
text:{
textAlign:'center',
fontSize: 19,
color:'white'
}
})
const mapStateToProps= (state) =>{
return {
favoritesFilm: state.toggleFavorite.favoritesFilm
}
}
export default connect(mapStateToProps)(FilmDetail)
这就是我现在要做的:
答案 0 :(得分:2)
我不清楚您的意思,但是可以在mapStateToProps中向道具添加多个状态,您不需要创建另一个函数,只要您也在商店中处理它
const mapStateToProps= (state) =>{
return {
favoritesFilm: state.toggleFavorite.favoritesFilm,
SeenFilm: state.any_store_state
}
}