Skip to content
A small library of helpers for using React Native with Fulcro
Clojure
Branch: develop
Clone or download
Latest commit f5c6a00 Oct 18, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src/main/com/fulcrologic/fulcro_native changed react factory to allow turning off or augmenting ui-text wrap… Oct 19, 2019
.gitignore updating deps Oct 8, 2019
CHANGELOG.md updated changelog Oct 12, 2019
README.adoc Assets caching (#2) Oct 18, 2019
deps.edn updated deps again Oct 8, 2019
pom.xml version Oct 19, 2019
shadow-cljs.edn

README.adoc

fulcro native

A small set of helpers for writing with React Native apps with Fulcro.

Fulcro itself works fine with React Native, but there are a few small configuration details that this library does for you. Additionally, it includes some things like factory helpers and wrappers for the standard React Native components.

1. Status

This library is in active development. It is useful, but incomplete.

2. Usage

Add the latest version to your project dependencies. At the moment the helper code only supports apps written with Expo, but if you look in expo-application you’ll see there isn’t much to change to work with non-expo apps.

We only test against the shadow-cljs build tool. If you’re using standard cljs compiler for npm deps then you’ll have to manage making sure react-native is available.

You will need the following NPM dependencies:

  • expo

  • react

  • react-native

  • create-react-class

3. Creating an Application

The standard com.fulcrologic.fulcro.expo-application/fulcro-app function needs a few configuration parameters to be changed to work with Native. This is done for you if you instead use the com.fulcrologic.fulcro-native.application/fulcro-app function, which is otherwise identical (it just passes your other options through).

(ns
  (:require
    [com.fulcrologic.fulcro-native.expo-application :as expoapp]
    [com.fulcrologic.fulcro.application :as app]))

(defonce app (expoapp/fulcro-app {}))


;; later (in entry point):

(app/mount! app RootComponent :native)

Calling mount! again will just refresh the UI.

4. Hot Code Reload

Be sure to disable both live reload and hot reload in the Expo system. Shadow-cljs will do hot code reload without them, and if they are enabled they will fight.

You’ll want your shadow-cljs config to include an after-load function that calls app/mount! to re-render the UI.

5. Loading Fonts and Images with Expo

Expo provides a mechanism to pre-load and cache fonts and static images during app startup. If you use the com.fulcrologic.fulcro-native.expo-application/fulcro-app function, this is taken care of for you. All you need to do is specify the images and/or fonts you want to cache in the app configuration, as follows:

(ns
  (:require
    [com.fulcrologic.fulcro-native.expo-application :as expoapp]
    [com.fulcrologic.fulcro.application :as app]))

; require images individually, so you can reference them when needed in the app
(defonce profile-blank (js/require "../assets/images/profile.png"))
(defonce background (js/require "../assets/images/background.png"))

(defonce images [profile-blank background])

(defonce fonts [["Roboto" (js/require "../node_modules/native-base/Fonts/Roboto.ttf")]
                ["Roboto_medium" (js/require "../node_modules/native-base/Fonts/Roboto_medium.ttf")]
                ["Avenir Next" (js/require "../assets/fonts/AvenirNext-Regular-08.ttf")]])


(defonce app (expoapp/fulcro-app {:cached-images images
                                  :cached-fonts fonts}))

Note that the asset paths are relative to the /app directory, or wherever you have set the output directory for the mobile app build.

6. Native Component Helpers

The com.fulcrologic.fulcro-native.alpha.components namespace includes functions that properly wrap many of the predefined components (if you want to add some, please feel free to send a PR). There is also a react-factory function in that namespace that can properly wrap React Native components, and does some nice automatic argument conversion for you: In particular if you use a raw string as a child, it will be auto-wrapped in a ui-text component with empty props:

;; You can write
(ui-button {} (ui-text {} "Hello"))
;; OR
(ui-button {} "Hello")

This namespace has an alpha component to it because we do want to evolve this API to do some of the same nice things that the DOM macros do, like making the props optional. Currently that is not supported.

7. React Factory

The element factory support includes component-local style support. This is a feature that we’re playing with while in Alpha, and will probably evolve. It allows you to co-locate style declarations in component options, and then apply them to the elements within. It uses the current value of Fulcro’s comp/parent to fine the styles. So, the basic usage right now is:

(ns my.app.ui
  (:require
    ["some-native-lib" :refer [FancyThing]]
    [com.fulcrologic.fulcro.components :as comp :refer [defsc]]
    [com.fulcrologic.fulcro-native.alpha.components :as nc :refer [react-factory ui-text ui-view]]
    ...))

(def ui-fancy-thing (react-factory FancyThing))

(defsc SomeComponent [this props]
  {:style {:bold {:fontWeight "bold"}
           :warning {:color "black"
                     :backgroundColor "red"}}
   ...other defsc options...}
  ;; normal style
  (ui-view {:style {:color "black"}}
    ;; Look up style in current component's options
    (ui-fancy-thing {:style :.bold}
       ;; Combine together styles from component's options with some optional normal ones
       (ui-text {:style {:marginLeft 10}
                 :styles [:.bold (when warning? :.warning)]} "Text"))))

If you want to use some other component’s style data, simply wrap it with a binding (NOTE: don’t render data-driven Fulcro components inside of such a binding or you’ll confuse things):

  (binding [comp/*parent* SomeComponent]
    (ui-text {:style :.bold} "Hi"))
You can’t perform that action at this time.