Как избежать дублирования данных при навигации по экрану? - PullRequest
0 голосов
/ 02 мая 2018

Моя ситуация - у меня есть два FlatList компонента (A и B).

А мой первый экран. Я использую react-navigation для навигации от A до B, B покажет стрелку назад на headerLeft. Когда я нажму на стрелку, он вернется к А. Но данные FlatList все еще показывают B, даже если это действительно в A ...

Мои данные взяты из API выборки react-redux, я думаю, что проблема в react-redux. Потому что я тестирую простой тест без react-redux. Проблема исчезла.

Я хочу использовать response-redux для создания моего проекта. Я пытаюсь использовать shouldComponentUpdate как

shouldComponentUpdate = (nextProps, nextState) => {
    if (nextProps.movieList === this.props.movieList) {
      return false;
    }
    return true;
  };

Моя проблема все еще не решена, когда goBack() к другому компоненту

Я console.log, он пытается выяснить, что происходит с моими реквизитами. Когда я перехожу к B из A. Мой console.log будет выглядеть следующим образом, я обнаружу, что компонент будет визуализирован ... enter image description here

Затем я щелкаю стрелку назад на headerLeft в A. Экран A, но данные все еще B, добавьте мой console.log одновременно пустым.

Я не могу понять это. Любая помощь будет оценена. Заранее спасибо.

Вот мой файл компонента A (B похож на 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.movie;
    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);

Вот мой файл компонента B:

import React, { Component } from 'react';
import { 
  View, FlatList, Dimensions, 
  Image, ActivityIndicator, Text
} from 'react-native';
import { connect } from 'react-redux';
import { fetchThisWeek } from '../actions';

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

class ThisWeek extends Component {
  static navigationOptions = ({ navigation }) => ({
    title: 'ThisWeek',
  });

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

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

  render() {
    const movieData = this.props.movieList.movie;
    console.log('B 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={1}
          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, { fetchThisWeek })(ThisWeek);

Вот мой MyListReducer.js:

import { 
  MOVIELIST_MAINACTIVITY,
  MOVIELIST_THISWEEK,
  MOVIELIST_THEATER
} from '../actions/types';

const INITIAL_STATE = {};

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {   
    case MOVIELIST_MAINACTIVITY:
      return action.payload;

    case MOVIELIST_THISWEEK:
      return action.payload;

    case MOVIELIST_THEATER:
      console.log(action.payload);
      return action.payload;

    default:
      return state;
  }
};

1 Ответ

0 голосов
/ 02 мая 2018

В вашем редукторе вы добавили извлеченные данные в основной объект в хранилище, вместо этого вам нужно будет поддерживать две разные переменные, чтобы сохранять данные этих разных компонентов отдельно. Попробуйте изменить редуктор как,

    import { 
      MOVIELIST_MAINACTIVITY,
      MOVIELIST_THISWEEK,
      MOVIELIST_THEATER
    } from '../actions/types';

    const INITIAL_STATE = {
      weeklyMovies:[],
      allMovies:[]
    };

    export default (state = INITIAL_STATE, action) => {
      switch (action.type) {   
        case MOVIELIST_MAINACTIVITY:
          return {
            ...state,
            allMovies:action.payload
         };

        case MOVIELIST_THISWEEK:
        return {
          ...state,
          weeklyMovies:action.payload
        };          

        case MOVIELIST_THEATER:
          console.log(action.payload);
          return action.payload;

        default:
          return {...state};
      }
    };

А в ваших компонентах A и B вы должны изменить свой mapStateToProps для чтения данных из соответствующих объектов в хранилище.

Для компонента MainActivity

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

и для компонента ThisWeek

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