How to use react navigation in cljs? - react-native

Here’s my code in which I’m trying to create multiple bottom tabs using react navigation
(defn sample-comp []
[:> View [:> Text "Sample Container!"]])
(defn root-comp []
[:> NavigationContainer
[:> SafeAreaView
(let [Tab (createBottomTabNavigator)]
[:> (.-Navigator Tab)
[:> (.-Screen Tab)
{:name "Home"
:component (r/reactify-component sample-comp)}]])]])
(defn init []
;; register error also occurs if there's a non-
;; related error in the code
(dispatch [:register-db])
(render-root "Humboi" (r/as-element [root-comp])))
but I’m getting the following error:
requireNativeComponent: “RNCSafeAreaProvider” was not found in UIManager.
How to fix this error?

Related

Using ReactNative External library in ClojureScript Project - Syntax

I am trying to use react-native-swipe-list-view inside clojurescript. But I am having some trouble in converting documented js code in cljs code.
Documentations:
import { SwipeRow } from 'react-native-swipe-list-view';
<SwipeRow>
<View>
</View>
</SwipeRow>
My Cljs Code:
(:require [react-native-swipe-list-view :as swipe_list])
(defn item[]
(
[swipe_list/SwipeRow
[:View]]
))
Online tool:
(def SwipeRow (.-SwipeRow (js/require "react-native-swipe-list-view")))
(defn item[]
(
[SwipeRow
[:View]]
))
None of the above worked. I am new to cljs. it will be a big help if someone can tell me how to convert the above lines of js into cljs. Thanks
Reagent Documents: Creating Reagent "Components" from React Components
Here I am going to create two reagent components, view and swipeRow. I am using different ways for both, to show two ways for importing library and creating components. You can use either.
;; Importing Reagent and React Native
(ns type_name_server_here
(:require [reagent.core :as reagent]
["react-native" :as rn]))
;; 1st Way: Importing SwipeRow
(def SwipeRowImport (.-SwipeRow (js/require "react-native-swipe-list-view")))
;; Converting it into Reagent Component
(def SwipeRow (reagent/adapt-react-class SwipeRowImport))
;; 2nd Way: Importing View from already imported react-native library and converting it into reagent component
(def view (reagent/adapt-react-class (.-View ^js rn)))
;; SwipeRow requires two children (Check out documentation)
(defn item[]
(
[SwipeRow
[view] [view]]
))
If you are using shadow-cljs, you can use this table as a reference, for converting ES6 Import statments to CLJS Require

How to properly import components from other files using reagent?

I want to use a reagent component I've created in another file/namespace, say this.is.the.namespace, and it contains a component defined like so:
(defn component-name []
; stuff
)
In my entry file, I do the following:
(ns entry.point.namespace.name
(:require [this.is.the.namespace]
))
And when I include [component-name] in a component in the entry file, the component doesn't show. Why might this be?
(ns this.is.the.namespace)
(defn component-name []
[:p "Hello There"])
(ns entry.point.namespace.name
(:require [reagent.core :as reagent]
[this.is.the.namespace :as my-components]))
(reagent/render [my-components/component-name] (js/getElementById "main-div"))
Change "main-div" to id of the div that you are rendering into.

RNRF: How open drawer with custom "hamburger?" Not documented in API. Error: "Actions.get" is not a function

I'm using the
<Drawer>
tag and it works great, but I don't want the default screen layout with the default "hamburger" menu icon at the top-left of the screen.
I've spent hours trying to get my own button to open the drawer.
I've done my research homework:
The RNRF API for Drawer doesn't list open/close methods:
Was happy to find two EXACT issues "How to open Drawer When use a custom icon in Scene" #1101 and "How to customize drawer button" #1078 on GitHub but none of the solutions work--so close but yet so far!
In Button component:
onPress={() => {Actions.get('drawer').ref.toggle()}}
but get this error:
Here is my main code:

Using react-native-camera in ClojureScript re-natal development

Has anyone used 'react-native-camera' component with re-natal?
I am just trying out the react-native-camera component in the default re-natal skeleton project.
My code is following
(ns wmshandheld.android.core
(:require [reagent.core :as r :refer [atom]]
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
[wmshandheld.events]
[wmshandheld.subs]))
(def ReactNative (js/require "react-native"))
(def ReactNativeCamera (js/require "react-native-camera"))
(def app-registry (.-AppRegistry ReactNative))
(def camera (.-Camera ReactNativeCamera))
(def text (r/adapt-react-class (.-Text ReactNative)))
(def view (r/adapt-react-class (.-View ReactNative)))
(def touchable-highlight (r/adapt-react-class (.-TouchableHighlight ReactNative)))
(defn alert [title]
(.alert (.-Alert ReactNative) title))
(defn app-root []
(fn []
[view {:style {:flex-direction "column" :margin 40 :align-items "center"}}
[camera {:ref (fn [cam]
(this-as this
(set! (.-camera this) cam)))
:style {:flex 1 :justify-content "flex-end" :align-items "center"}
:aspect (.-fill (.-Aspect (.-constants camera)))}
[text {:style {:flex 0 :background-color "#fff"
:border-radius 5 :color "#000"
:padding 10 :margin 40}
:on-press #(alert "HELLO!")}
"[CAPTURE]"]]]))
(defn init []
(dispatch-sync [:initialize-db])
(.registerComponent app-registry "WMSHandheld" #(r/reactify-component app-root)))
But I got such an error.
console.error: "Error rendering component (in wmshandheld.android.core.app_root)"
error
YellowBox.js:71:16
finishClassComponent
ReactNativeFiber-dev.js:1667:86
updateClassComponent
ReactNativeFiber-dev.js:1659:33
beginWork
ReactNativeFiber-dev.js:1786:44
performUnitOfWork
ReactNativeFiber-dev.js:2528:33
workLoop
ReactNativeFiber-dev.js:2554:141
_invokeGuardedCallback
ReactNativeFiber-dev.js:73:23
invokeGuardedCallback
ReactNativeFiber-dev.js:47:40
performWork
ReactNativeFiber-dev.js:2593:41
scheduleUpdateImpl
ReactNativeFiber-dev.js:2728:101
scheduleUpdate
ReactNativeFiber-dev.js:2711:38
enqueueSetState
ReactNativeFiber-dev.js:1514:90
setState
react.development.js:218:31
<unknown>
figwheel-bridge.js:88:33
waitForFinalEval
figwheel-bridge.js:197:21
<unknown>
figwheel-bridge.js:28:17
fireEvalListenters
figwheel-bridge.js:27:41
<unknown>
figwheel-bridge.js:118:24
tryCallOne
core.js:37:14
<unknown>
core.js:123:25
<unknown>
JSTimers.js:301:23
_callTimer
JSTimers.js:154:6
_callImmediatesPass
JSTimers.js:202:17
callImmediates
JSTimers.js:470:11
__callImmediates
MessageQueue.js:278:4
<unknown>
MessageQueue.js:145:6
__guard
MessageQueue.js:265:6
flushedQueue
MessageQueue.js:144:17
callFunctionReturnFlushedQueue
MessageQueue.js:119:11
Does anyone know what is the problem? and how to solve it? just a bare working example that uses react-native-camera on github or gist would be perfect!...
If this helps this is how I can atleast get the camera to display in the emulator. I havent pasted the whole code but by using [view [camera-component]] in the app root the emulator shows the back camera component. Hope this helps
(def ReactNativeCamera (js/require "react-native-camera"))
(def camera (r/adapt-react-class (.-RNCamera ReactNativeCamera)))
(defn camera-component
[]
(let data {}]
(fn []
[view
[text "hello"]
[camera {
:ref (fn [cam] (this-as this (set! (.-Camera this) cam)))
:style {:flex 1 :justify-content "flex-end" :align-items "center" :border-color "black" :border-width 1 :min-height "10%"}
:type (-> ReactNativeCamera .-RNCamera .-Constants .-Type .-back)
:permission-dialog-title "Permission to use camera"
:permission-dialog-message "Need permission to use camera on your phone"}]])))

How to use StackNavigator of React Navigation in clojurescript

I am new to clojurescript and reagent. I try to use react-navigation in my react-native app but I getting this error
Error rendering component (in env.main.reloader > exp_cljs.core.app_root > reagent2)
This is my code
(def react-navigation (js/require "react-navigation"))
(def StackNavigator (aget react-navigation "StackNavigator"))
(defn Home
[]
[text "Hello Navigator"])
(defn SimpleApp
[]
(StackNavigator
(clj->js {:Home {:screen (r/create-class {:reagent-render (Home)})}})))
(defn init []
(dispatch-sync [:initialize-db])
(.registerComponent rn/app-registry "main" #(r/reactify-component app-root)))
This is my app-root
(defn app-root []
(SimpleApp)); -- error
;(r/create-class {:reagent-render SimpleApp}); error
;(r/as-element (SimpleApp)); -- error
;(r/adapt-react-class SimpleApp)); -- error
(ns same.app
(:require [reagent.core :as r]
[same.ui :as ui]
[same.util :as u]
[same.screens.auth :refer [AuthScreen]]
; [same.screens.reg :refer [RegScreen]]
; [same.screens.resend :refer [ResendScreen]]
[same.screens.splash :refer [SplashScreen]]
; [same.screens.drawer :refer [Drawer]]
[same.screens.presentation :refer [Presentation]]))
(def routes #js {;:Drawer #js {:screen (r/reactify-component Drawer)}
:AuthScreen #js {:screen (r/reactify-component AuthScreen)}
;:RegScreen #js {:screen (r/reactify-component RegScreen)}
;:ResendScreen #js {:screen (r/reactify-component ResendScreen)}
:Presentation #js {:screen (r/reactify-component Presentation)}
:Splash #js {:screen (r/reactify-component SplashScreen)}})
(def Routing (ui/StackNavigator.
routes
#js {:initialRouteName "Splash"
:headerMode "none"
:mode "modal"}))
(def routing (r/adapt-react-class Routing))
(defn AppNavigator []
(fn []
[routing]))
and android.core:
(ns same.android.core
(:require [reagent.core :as r :refer [atom]]
[re-frame.core :refer [dispatch-sync]]
[same.ui :as ui]
[same.events]
[same.subs]
[same.app :refer [AppNavigator]]))
(aset js/console "disableYellowBox" true)
(defn app-root []
(fn []
[AppNavigator]))
(defn init []
(dispatch-sync [:initialize-db])
(.registerComponent ui/app-registry "Same" #(r/reactify-component app-root)))
The trick is to convert React Native components to Reagent components and back where needed. In the following example definitions of login-screen and main-screen are omitted, they're just regular Reagent components.
(def react-navigation (js/require "react-navigation"))
(def stack-navigator (.-createStackNavigator react-navigation))
(def switch-navigator (.-createSwitchNavigator react-navigation))
; ...
; ...
; ...
(defn application-nav-stack []
(stack-navigator (clj->js { "MainApp" (r/reactify-component main-screen) })))
(defn authentication-nav-stack []
(stack-navigator (clj->js { "Login" (r/reactify-component login-screen) })))
(defn app-navigation-switch []
(switch-navigator
(clj->js { :Auth (authentication-nav-stack) :MainApp (application-nav-stack) })
(clj->js { :initialRouteName :Auth } )))
(defn app-root []
[ (r/adapt-react-class (app-navigation-switch)) ] )
(defn init []
(dispatch-sync [:initialize-db])
(.registerComponent app-registry "MyApp" #(r/reactify-component app-root)))
Whenever you pass a Reagent component to ReactNavigation function you need to use reactify-component to convert it to the native JS form; whenever you need to use ReactNavigation component as a part of Reagent component, you need to use adapt-react-class to convert it back.