项目作者: martinmoec

项目描述 :
Fable bindings for the @react-navigation/native, @react-navigation/stack and @react-navigation/bottom-tabs modules.
高级语言: F#
项目地址: git://github.com/martinmoec/Fable.ReactNative.Navigation.git
创建时间: 2020-08-24T15:23:20Z
项目社区:https://github.com/martinmoec/Fable.ReactNative.Navigation

开源协议:

下载


Fable.ReactNative.Navigation

Provides Fable bindings for the stack and bottom-tabs navigators of React Navigation.

View the requirements and read the docs on getting started with React Navigation here.

When building Elmish-applications in React Native larger than the infamous “Counter app”, navigating in the native way of iOS and Android quickly becomes wonky. This package lets you make use of the stack navigator of React Navigation, in order to get a native feel and look when navigating in your Fable React Native apps.

Install

Assuming a similar setup to the one described in this how-to.

  • Add the Fable.ReactNative.Navigation Nuget package to your F# project

  • Install the required npm-modules

    • @react-navigation/native, @react-navigation/stack,@react-navigation/bottom-tabs, @react-navigation/drawer, react-native-gesture-handler, react-native-reanimated, react-native-safe-area-context, react-native-screens, @react-native-community/masked-view (See the React Navigation docs)

Register your application

When using React Navigation you, simplified, provide the app with a set of screens and a function for rendering these, and React Navigation will handle the rest. The classic Elmish setup does not work too well with this approach. As an alternative to registering your application with Elmish at the core through withReactNative, this package provides a helper function for registering your application. Fable.ReactNative.Navigation.Helpers.registerApp takes the name of your application (from react-native init) and your base navigationContainer as an input. For example, if i followed the how-to linked at the top, with react-native init demo:

  1. open Fable.ReactNative.Navigation
  2. let homePage () : Fable.React.ReactElement =
  3. ...
  4. let loginPage () : Fable.React.ReactElement =
  5. ...
  6. let StackNavigator = Stack.CreateStackNavigator()
  7. let render =
  8. navigationContainer [] [
  9. StackNavigator.Navigator.navigator [
  10. Stack.NavigatorProps.InitialRouteName "home"
  11. ] [
  12. StackNavigator.Screen.screen "home" homePage [] []
  13. StackNavigator.Screen.screen "login" loginPage [] []
  14. ]
  15. ]
  16. Helpers.registerApp "demo" render

Here an app is registered with two screens, home and login, which will be handled with the homePage and loginPage functions respectively. The navigation handler of React Navigate will call the respected function for each screen added to the stack. From here you can build the functionality for each screen as you wish, for example using an MVU-architecture with useReducer (see sample).

Navigating and passing data between screens

The navigation handler of React Navigate provides every screen-handler function with a navigation-object. You can access this, with its bindings, as follows.

  1. open Fable.ReactNative.Navigation
  2. open Fable.ReactNative.Navigation.Types
  3. ...
  4. let loginPage ( navigation : INavigation<int>) =
  5. ...
  6. let StackNavigator = Stack.CreateStackNavigator ()
  7. let render =
  8. navigationContainer [] [
  9. StackNavigator.Navigator.navigator [
  10. Stack.NavigatorProps.InitialRouteName "home"
  11. ] [
  12. StackNavigator.Screen.screen "home" home [] []
  13. StackNavigator.Screen.screen "login" loginPage [] []
  14. ]
  15. ]
  16. Helpers.registerApp "demo" render

Here the loginPage expects to receive a navigation object, where the data payload is an integer. The payload can be accessed through navigation.route.params.

The navigation object provides functions for navigating further. For example, you can navigate to the home page using

  1. navigation.navigation.navigate "home"

where "home" is the name of the screen registered in the navigationContainer. Other examples are push("home"), goBack(), pop() and popToTop(). See the React Navigation docs for more.

The package provides you with helper functions for navigating and pushing screens with data, navigateWithData and pushWithData, which takes the navigation object, the screen name and your data.

  1. open Fable.ReactNative.Navigation
  2. open Fable.ReactNative.Navigation.Types
  3. let HomeScreenName = "home"
  4. let LoginScreenName = "login"
  5. let homePage ( nav : INavigation<_> ) =
  6. view [] [
  7. text [] "Navigate"
  8. |> touchableHighlightWithChild [
  9. OnPress ( fun _ -> navigateWithData nav LoginScreenName "This text is passed" )
  10. ]
  11. ]
  12. let loginPage ( nav : INavigation<string> ) =
  13. view [] [
  14. text [] ( sprintf "Received: %s" nav.route.params )
  15. ]
  16. let StackNavigator = Stack.CreateStackNavigator ()
  17. let render =
  18. navigationContainer [] [
  19. StackNavigator.Navigator.navigator [
  20. Stack.NavigatorProps.InitialRouteName HomeScreenName
  21. ] [
  22. StackNavigator.Screen.screen HomeScreenName homePage [] []
  23. StackNavigator.Screen.screen LoginScreenName loginPage [] []
  24. ]
  25. ]
  26. Helpers.registerApp "demo" render

Notice

As you might have noticed, the type-safety of F# is not preserved between the data passed with the navigation function and the screen-function receiving the data, as it essentially is the navigation handler of React Navigation which will call your screen functions.