【问题标题】:addListeners doesn't work from time to time - React native tab navigationaddListeners 有时不起作用 - 反应本机选项卡导航
【发布时间】:2020-05-16 15:56:43
【问题描述】:

我使用了 react-navigation 的标签导航。每次按下选项卡时,我都需要在 componentDidMount 中调用 loadData 函数。所以我在其中使用了 addListener 。但问题是显示数据花费的时间太长。有时它可以无缝运行,有时它一直只显示“正在加载数据......”。 我是否正确使用了 addListener?提前致谢。

Home.js

state = {
  storageCheck: true
};

componentDidMount() {
    this._unsubscribe = this.props.navigation.addListener('willFocus', () => {
      this.loadData();
    });
}

componentWillUnmount() {
    this._unsubscribe.remove();
}

loadData = () => {
    this.setState({
        storageCheck: false
    })
}

render() {
if (this.state.storageCheck) {
  return <View>
    <Text>Loading Data...</Text>
  </View>
}
return (
    <View>
        <Text>Data</Text>
    </View>
)}

标签导航

const TabNavigator = createBottomTabNavigator({
  Home: {
    screen: Home
  },
  Profile: {
    screen: Profile,
    navigationOptions: ({ navigation }) => ({
      // title: 'Profile',
    })
  },
  Setting: {
    screen: Setting,
  }
},
  {
    defaultNavigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, tintColor }) => {
        const { routeName } = navigation.state;
        let iconName;
        if (routeName === 'Home') {
          iconName = 'home';
        } else if (routeName === 'Profile') {
          iconName = 'account-circle';
        } else if (routeName === 'Setting') {
          iconName = 'settings';
        }

        return <MaterialIcons name={iconName} size={28} color={tintColor} />;
      },
    })
  }
);

export default createAppContainer(TabNavigator);

【问题讨论】:

    标签: react-native react-navigation react-navigation-bottom-tab


    【解决方案1】:

    在反应导航 v4 中。

    您可以使用 await-async 函数。

    state = {
      storageCheck: true,
      loader: true,
      someData: null
    };
    
    componentDidMount() {
        this._unsubscribe = this.props.navigation.addListener('willFocus', () => {
          this.loadData();
        });
    }
    
    componentWillUnmount() {
        this._unsubscribe.remove();
    }
    
    loadData = async() => {
        this.setState({
            someData: await AsyncStorage.getItem("SOME_KEY"),
            storageCheck: false,
            loader: false
        })
    }
    
    render() {
      return (
          <View>
           {this.state.someData ? (
            <Text>data is loaded</Text>
           ) : (
            <Text> loading ... </Text>
           )}
          </View>
      )
    }

    干杯!

    【讨论】:

      【解决方案2】:

      这是一个明确的解决方案。我认为你可以使用 hooksfunction component。 我使用与此相关的解决方案

      import React, { useState, useEffect } from "react";
      import { 
          View,
          Text,
          ActivityIndicator
      } from "react-native";
      import { useIsFocused } from "@react-navigation/native";
      
      const TestComp = () => {
      
          const [storageCheck, setStorageCheck] = useState(false);
          const [isLoaded, setIsLoaded] = useState(false);
          const isFocused = useIsFocused();
      
          useEffect(() => {
              const loadData = async() => {
                  setStorageCheck(true);
                  setIsLoaded(true);
              }
              loadData();
          }, [isFocused])
      
      
          return(
              <>
                  {isLoaded ? (
                      <View>
                          <Text>some data or texts..</Text>
                      </View>
                  ) : (
                      <ActivityIndicator />
                  )}
              </>
          )
      }
      export default TestComp;

      干杯!

      【讨论】:

      • 我有一个旧项目,所以我现在无法更改它。而且我使用过 react navigation v4。
      • 对于 v4,您应该使用 NavigationEvents 组件。 &lt;NavigationEvents onWillFocus={() =&gt; this.fetchData()} { // enter page component container } &lt;/NavigationEvents&gt; 文档:NavigationEvents
      • 我也尝试过 navigationEvents。但是我必须从异步存储中检索数据,这会使布局在显示真实数据之前闪烁一毫秒。所以我搬到了 addListener。
      • 你试过了吗? loadData = async() =&gt; { this.setState({ key: await AsyncStorage.getItem("SOMEKEY"), loader: false }); } 在渲染函数中:render(){ this.state.loader ? ( &lt;ActivityIndicator /&gt; ) : ( &lt;View /&gt; ) }
      • tysm Eftal... 你拯救了我的一天。在 setState 中使用 await 效果很好。请在答案中包含此行,我会接受答案。
      猜你喜欢
      • 2020-07-10
      • 2020-06-29
      • 1970-01-01
      • 1970-01-01
      • 2020-04-19
      • 1970-01-01
      • 2017-11-22
      • 2023-01-27
      • 1970-01-01
      相关资源
      最近更新 更多