После 2 дней исследований со стороны я надеюсь найти ответ здесь!
Я звоню API, чтобы получить список фильмов. Фильмы отображаются в виде «Новые фильмы»
. В этом представлении у меня есть две возможности: поместить фильм в избранное (нажав на значок «сердце») И нажать на синюю кнопку с надписью «Я видел этот фильм "
. Для этого я использую реаги-редукс. До сих пор, когда я ставлю фильм как любимый, он работает;Состояние изменяется (см. Функцию mapStateToProps ()), и я извлекаю этот фильм, нажимая на вкладку панели навигации ниже (см. Прикрепленный файл)
Теперь я пытаюсь приблизительно выполнить то же самое для того жекласс «FilmDetail», когда я нажимаю на кнопку «Я видел этот фильм», за исключением того, что фильмы будут отображаться на вкладке «просмотренные» (см. прикрепленный файл).
Поэтому мой вопрос заключается в том, как создать еще одну mapStateToProps ()в том же классе поменять состояние и сделать так, чтобы фильм появлялся во вкладке «видно»?
Я пытался сделать что-то в функции componentDidMount (), но это не работает. Может быть, есть концепция реактивного редукса, которого я пока не знаю.
это полный код (он работает для страницы избранного)
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)
И это то, что мне нужно сделатьсейчас: