Как я могу использовать componentDidMount для вкладок?

#react-native #react-navigation

#react-native #реакция-навигация

Вопрос:

У меня есть три вкладки с помощью react-navigation и createMaterialTopTabNavigator . Теперь я хочу отобразить некоторые данные на вкладках с помощью json и componentDidMount , но у меня возникает эта ошибка, когда я помещаю componentDidMount в две вкладки:

null не является объектом (вычисление ‘this.state.DataSource’)

Когда я использую componentDidMount на одной вкладке, все в порядке и работает нормально.

Одна из моих вкладок:

 export default class HomeTabScreen extends React.Component{

componentDidMount(){
    return fetch('men-cat.php')
    .then((response)=>response.json()).
    then((responseJson)=>{
      let ds = new ListView.DataSource({rowHasChanged:(r1,r2)=>r1!=r2});
      this.setState({
        isLoading:false,
        dataSource:ds.cloneWithRows(responseJson)
      });
    }).done();
  }

  render() {
    return (
      <ScrollView>
      <ListView style={{zIndex:1}}
        contentContainerStyle={styles.list}
        dataSource={this.state.dataSource}
        enableEmptySections={true}
        renderRow={ (rowData)=>

            <View style={styles.cats}>
              <TouchableOpacity activeOpacity={0.8} onPress={()=>{this.props.navigation.navigate('Products' , {
                title: rowData.name,
              })}}>
                <ImageBackground source={{uri:rowData.thumb}} imageStyle={{ borderRadius: 5 }} style={styles.imgBgCats}>
                  <Text style={styles.homeCatsCostTitle}>{rowData.name}</Text>
                </ImageBackground>
              </TouchableOpacity>
            </View>
          }
          />
    </ScrollView>

    );
  }
}
  

root:

 const MenStack = createStackNavigator({
  menStackNav: { screen: MenTabScreen,    navigationOptions:{tabBarVisible: false},
},
  Products: {
    screen: ProductsShow,
    navigationOptions:{tabBarVisible: false},
  },
},{
  initialRouteName: 'menStackNav',
  headerMode: 'none',
  navigationOptions: {
    headerVisible: false,
  }
});

MenStack.navigationOptions = ({navigation}) => {
      let tabBarVisible = true;
      if(navigation.state.index > 0){
        tabBarVisible = false;
      }

      return {
        tabBarVisible,
      }
}

const HomeScreenTabs = createMaterialTopTabNavigator({
  Home:{
    screen:HomeTabScreen,
  },
  Women: {
    screen:WomenTabScreen,
  },
  Men: {
    screen:MenStack,
  },

},{
  tabBarOptions: {
    style:{backgroundColor:'#fff'},
    activeTintColor: '#0077FF',
    inactiveTintColor: '#0077FF60',
    indicatorStyle: {
      opacity: 0
    },
    tabStyle:{backgroundColor:'#fff',height:40,borderBottomColor:'#fff'},
    labelStyle: {
      borderBottomColor:'#fff',
        fontSize: 14,
      },
  },
    initialRouteName: 'Men',
    mode: 'modal',
    headerMode: 'none',
});
  

Комментарии:

1. Покажите нам какой-нибудь код, пожалуйста. Что вы уже пробовали? Откуда вы получаете эту ошибку?

2. @Vencovsky Теперь вы можете видеть мои коды. Эта ошибка — все, что я вижу в консоли.. Я думаю, что я должен использовать componentDidMount один раз для всех вкладок, но я не знаю, как я могу это сделать..

Ответ №1:

Ошибка, которую вы получаете, возникает из-за того, что, пока ваша выборка ожидает ответа, функция визуализации пытается отобразить ListView с несуществующим источником данных.

Вы можете устранить проблему, установив начальное значение в состоянии на пустой источник данных или, альтернативно, добавьте проверку в функцию визуализации, которая будет отображать только ListView , если источник данных не равен null.

 {!!this.state.dataSource amp;amp;
 <ListView
    ...
 />}
  

Наконец, ListView устарел и был заменен на FlatList , который имеет гораздо более дружественный API.

Комментарии:

1. Убедитесь, что вы добавили условие во все вкладки.

2. существует ли какое-либо другое использование this.state.dataSource , которое не защищено условием?

3. Попробуйте инициализировать состояние с помощью пустого источника данных.