使用react-navigation初始化数据加载的位置

时间:2017-11-02 08:22:35

标签: react-native redux react-navigation

我正在使用react-navigation,这是我的结构:

根堆栈导航器:

export const Root = StackNavigator({
Index: {
    screen: Index,
    navigationOptions: ({ navigation }) => ({

    }),
},
Cart: {
    screen: Cart,
    navigationOptions: ({ navigation }) => ({
        title: 'Votre panier',
        drawerLabel: 'Cart',
        drawerIcon: ({ tintColor }) => <Icon theme={{ iconFamily: 'FontAwesome' }} size={26} name="shopping-basket" color={tintColor} />
    }),
},
...

我的结构如下:

  
      
  • StackNavigator(Root)      
        
    • DrawerNavigator(索引)      
          
      • TabNavigator的      
            
        • 我的页面
        •   
        • MyPage(使用不同数据格式化的同一页面)
        •   
        • ...
        •   
      •   
    •   
  •   

所以我的问题是,我在哪里加载数据,初始化我的应用程序?我需要调用一次,在其他页面之前调用。

我的应用程序中显示的第一页是MyPage页面。但正如你所看到的,由于TabNavigator,如果我将我的函数放入其中,它将被多次调用。

有人会在启动画面中说,但是我使用的是主splashscreen component,而我没有很多控件。

我想到了我们创建提供程序的App.js,但我认为这不是一个好主意?

const MyApp = () => {

    //TODO We're loading the data here, I don't know if it's the good decision
    ApplicationManager.loadData(store);
    SplashScreen.hide();

    return (
        <Provider store={store}>
            <Root/>
        </Provider>
    ); 
};

这样做的好方法是什么?

4 个答案:

答案 0 :(得分:3)

class MyApp extends Component {

  state = {
    initialized: false
  }

  componentWillMount() {
    // if this is a promise, otherwise pass a callback to call when it's done
    ApplicationManager.loadData(store).then(() => {
      this.setState({ initialized: true })
    })
  }

  render() {
    const { initialized } = this.state
    if (!initialized) {
      return <SplashScreen />
    }
    return (
      <Provider store={store} >
        <Root />
      </Provider>
    );
  }
}

答案 1 :(得分:2)

TabNavigator默认情况下会同时渲染/加载其所有子组件,但如果设置属性lazy: true组件将仅在您导航时呈现。这意味着您的功能不会被多次调用。

const Tabs = TabNavigator(
    {
      MyPage : {
        screen: MyPage
      },
      MyPage2 : {
        screen: MyPage,
        }
      }
    },
    {
        lazy: true
    }
);

如果您使用此结构并在MyPage内部调用获取数据,则可以在componentWillReceiveProps中添加逻辑,该逻辑将检查已存储的数据和/或在获取新数据之前是否已更改。从MyPage调用您的提取功能使您能够在每个页面/屏幕访问时提取新数据,或者如果您需要,可以“拉动刷新”。

您还可以在启动画面时间中提取初始数据,我不建议您同时提取所有应用数据,所有屏幕的数据,因为您可能不需要同时使用所有屏幕。你可以这样做:

class MyApp extends Component {

  state = {
    initialized: false
  }

  componentWillMount() {
    // if this is a promise, otherwise pass a callback to call when it's done
    ApplicationManager.loadData(store).then(() => {
      this.setState({ initialized: true })
    })
  }

  render() {
    const { initialized } = this.state
    if (!initialized) {
      return null
    }
    return (
      <Provider store={store} >
        <Root />
      </Provider>
    );
  }
}

class Root extends Component {
    componentDidMount() {
        SplashScreen.hide();
    }
...
}

答案 2 :(得分:0)

您应该在<html> <head> <div id="particles-js"></div> <script src="particles.js"></script> <title>MYMDB</title> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.css"> <link rel="stylesheet" type="text/css" href="/stylesheets/app.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> </head> <body> </body> </html> 或初始化App.js的位置执行此操作。如果我是你,我会设置一个加载屏幕,一旦数据准备就会被StackNavigator结构取代。

答案 3 :(得分:0)

我不会在应用程序中执行此操作,因为您失去了控制权。遗憾的是我没有使用react-navigation或redux但是我看到TabNavigator有一个tabBarOnPress方法,我会用它来触发加载。您可以按需加载每个页面数据。

https://reactnavigation.org/docs/navigators/tab#tabBarOnPress