react-navigation / redux-helpers

Redux middleware and utils for React Navigation
Other
296 stars 43 forks source link

Render component is strange when click back arrow with react-redux #27

Closed motogod closed 6 years ago

motogod commented 6 years ago

I have two class component A and B, i navigate to B by using this.props.navigation.navigate('B') then B component will have a back arrow on headerLeft, when i click the back arrow my data is still using B component data although my screen is A component.

I want to know what is going on when i click the back arrow, i try to console.log in A and B under their render function, i find it will render B > A > B

If i don't click the back arrow button only navigate it by using this.props.navigation.navigate('B or A'), the problem is gone.

My data is come from fetch API with react-redux. I try a simple test to fetch API without react-redux, the problem is gone too.

I have no idea the issue come from react-navigation or react-redux.

Thanks in advance.

Here is my A component file (B component file is similar with A):

import React, { Component } from 'react';
import { 
  View, FlatList, Dimensions, 
  TouchableOpacity, Image,
  ActivityIndicator, Alert, Platform
} from 'react-native';
import { Icon } from 'react-native-elements';
import { connect } from 'react-redux';
import { fetchMainMovieList } from '../actions';

const { width, height } = Dimensions.get('window');
const equalWidth = (width / 2);

class MainActivity extends Component {
  static navigationOptions = ({ navigation }) => ({
    title: 'MainActivity',
    headerLeft: 
      <TouchableOpacity style={{ marginLeft: 10 }} onPress={() => navigation.navigate('DrawerOpen')} >
        <Icon name='menu' />
      </TouchableOpacity>
  });

  componentWillMount() {
    this.props.fetchMainMovieList();
  }

  renderItem({ item }) {
    return (
      <View>
        <Image 
          source={{ uri: item.photoHref }} 
          style={{ height: 220, width: equalWidth }} 
          resizeMode="cover" 
        />
      </View>
    );
  }

  render() {
    const movieData = this.props.movieList;
    console.log('A component this.props=>');
    console.log(this.props);
    if (movieData === []) {
      return (
        <View style={styles.loadingStyle}>
          <ActivityIndicator />
        </View>
      );
    }
    return (
      <View style={{ flex: 1 }}>
        <FlatList
          data={movieData}
          renderItem={this.renderItem} 
          numColumns={2}
          horizontal={false}
          keyExtractor={(item, index) => index} 
        />
      </View>
    );
  }
}

const styles = {
  loadingStyle: {
    flex: 1, 
    flexDirection: 'column', 
    justifyContent: 'center', 
    alignItems: 'center'
  }
};

const mapStateToProps = (state) => {
  const movieList = state.movieList;
  return movieList;
};

export default connect(mapStateToProps, { fetchMainMovieList })(MainActivity);

Current Behavior

What code are you running and what is happening?
Click back arrow on headerLeft in B component to A component , the data is still using B component data.

Expected Behavior

What do you expect should be happening?
Click back arrow on headerLeft in B component to A component , it should render A component only once not B > A > B

Include a screenshot if it makes sense.

2018-05-02 8 52 55
software version
react-navigation "^1.5.11"
react-native "~0.55.2"
react-redux "^5.0.7"
Ashoat commented 6 years ago

Your mapStateToProps need to return an object containing the props you want to merge, not just a single prop.