在同一页面上执行两个不同的操作时,如何处理mapStateToProps()函数?

时间:2019-10-23 12:00:53

标签: react-native react-redux react-native-navigation

经过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)

这就是我现在要做的:

enter image description here

1 个答案:

答案 0 :(得分:2)

我不清楚您的意思,但是可以在mapStateToProps中向道具添加多个状态,您不需要创建另一个函数,只要您也在商店中处理它

    const mapStateToProps= (state) =>{
      return {
        favoritesFilm: state.toggleFavorite.favoritesFilm,
        SeenFilm: state.any_store_state
    }
  }