cljs-react-navigation icon indicating copy to clipboard operation
cljs-react-navigation copied to clipboard

Duplicate screen generated on navigation

Open binora opened this issue 7 years ago • 4 comments

Hi, I have attached a gif and the relevant code for the same.

duplicate_screen2

router.cljs

(ns my-app.router
  (:require [my-app.screens :refer [sign-in-screen second-screen ]]
            [cljs-react-navigation.re-frame :refer [stack-navigator
                                                    stack-screen]]))

(def MyStack (stack-navigator
                          {:sign-in
                           {:screen (stack-screen sign-in-screen
                                                  {:title "1"})}
                           :second
                           {:screen (stack-screen second-screen
                                                  {:headerTitle "2"})}}))

screens.cljs


(ns my-app.screens
  (:require [reagent.core :as r :refer [atom]]
            [re-frame.core :refer [subscribe dispatch dispatch-sync]]
            [my-app.handlers]
            [my-app.ui :refer [text view image text-input
                               dimensions gifted-chat alert
                               flat-list activity-indicator
                               touchable-highlight]]
            [my-app.subs]))

(defn sign-in-screen [{:keys [navigation screenProps] :as props}]
  (let [{:keys [navigate]} navigation
        state (r/atom {:username ""})
        get-text #(-> % .-nativeEvent .-text)
        on-input-change (fn [value]
                          (swap! state assoc :username (get-text value)))
        on-press (fn []
                   (navigate "second"))]
    (fn [props]
      [container
       [view {:width "70%"
              :flex-direction "column"
              :align-items "center"}
        [text-input {:style {:height 40
                             :width "100%"}
                     :placeholder "Enter username"
                     :borderWidth 1
                     :margin-bottom 20
                     :textAlign "center"
                     :value (:username @state)
                     :on-change on-input-change}]
        [touchable-highlight {:on-press on-press}
         [text "Go"]]]])))

(defn second-screen [{:keys [navigation] :as props}]
  (fn [props]
    [container [view [text "hello"]]]))

db.cljs

(ns my-app.db)


(defonce default-routes (clj->js {:index 0
                                  :routes [{:key "1"
                                            :routeName "sign-in"}
                                           {:key "2"
                                            :routeName "second"}]}))
;; initial state of app-db
(defonce app-db {:greeting "Hello Clojurescript in Expo!"
                 :routing default-routes})

binora avatar Nov 21 '17 00:11 binora

@binora I am having a similar issue - which version of the lib are you using? Did you ever figure out what was causing this?

andrew-nguyen avatar Jul 29 '18 17:07 andrew-nguyen

@andrew-nguyen i was using version 0.1.1. I couldnt solve it. This wasnt a bug in this library but react-navigation itself I think. This is a simliar issue : https://github.com/react-navigation/react-navigation/issues/2904

binora avatar Jul 31 '18 18:07 binora

@binora Thanks for the link. One thing I've noticed (using 0.1.3) is that the double-rendering only occurs in one of two situations for me:

  1. After a figwheel reload (a button that was rendering only once prior to the reload is now double-rendering)
  2. If I specify a stack of screens in a re-frame event and then navigate to that stack of screens

andrew-nguyen avatar Jul 31 '18 18:07 andrew-nguyen

Not sure if this explains the behavior or if it's the correct fix but here's what I've done with my fork:

  1. re-frame app-db stores clojure data structures (I did this primarily because I use the params feature to pass data to subsequent screens and ended up with a mix of clojure and js data structures within app-db. It seemed that always storing clojure structures and converting to js when necessary was the best path.)
  2. cljs-react-navigation.re-frame functions have been changed to explicitly convert to js data structures (and back to clojure data structures when saving to app-db)
  3. All of my downstream code now uses (dispatch-sync :cljs-react-navigation.re-frame/navigate ...) to navigate instead of the functions contained within the props

Everything generally appears to be working as expected.

@seantempesta If this makes sense, I'm happy to clean up my fork and submit a PR

andrew-nguyen avatar Aug 02 '18 23:08 andrew-nguyen