Skip to content

Commit 3b6b2a2

Browse files
ulisesmacVolodLytvynenko
authored andcommitted
Avoid blinking by using rn/memo
1 parent 5924b6d commit 3b6b2a2

File tree

1 file changed

+44
-34
lines changed

1 file changed

+44
-34
lines changed

src/react_native/fast_image.cljs

+44-34
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,69 @@
11
(ns react-native.fast-image
22
(:require
3-
["react-native-fast-image" :as FastImage]
4-
[react-native.core :as rn]
5-
[reagent.core :as reagent]))
3+
["react-native-fast-image" :as FastImage]
4+
[clojure.string :as string]
5+
[oops.core :as oops]
6+
[react-native.core :as rn]
7+
[reagent.core :as reagent]))
68

7-
(def internal-fast-image (reagent/adapt-react-class ^js FastImage))
9+
(defn- build-source
10+
[source]
11+
(if (string? source)
12+
{:uri source
13+
:priority :high}
14+
source))
15+
16+
(defn- remove-port
17+
[source]
18+
(if (string? source)
19+
(string/replace-first source #":\d+" "")
20+
(string/replace-first (oops/oget source :uri) #":\d+" "")))
821

922
(defn- placeholder
1023
[{:keys [style fallback-content error? loaded?]}]
11-
[rn/view
12-
{:style (assoc style
13-
:flex 1
14-
:justify-content :center
15-
:align-items :center)}
24+
[rn/view {:style (assoc style
25+
:flex 1
26+
:justify-content :center
27+
:align-items :center)}
1628
(cond
1729
(and error? fallback-content) fallback-content
1830
error? [rn/text "X"]
1931
(not loaded?) [rn/activity-indicator {:animating true}])])
2032

21-
(defn- get-source
22-
[source]
23-
(if (string? source)
24-
{:uri source
25-
:priority :high}
26-
source))
27-
28-
;; NOTE: We need to use ratoms to avoid the flickering since their state is updated
29-
;; altogether at the end of the frame (different from hooks), this allows us to display
30-
;; both uses of `internal-fast-image` always in sync.
31-
(defn fast-image
33+
;; We cannot use hooks since `reactify-component` seems to ignore the functional compiler
34+
(defn- internal-fast-image
3235
[_]
3336
(let [loaded? (reagent/atom false)
3437
error? (reagent/atom false)
35-
previous-source (reagent/atom nil)
3638
on-image-error (fn [event on-error]
3739
(when (fn? on-error) (on-error event))
3840
(reset! error? true))
39-
on-image-loaded (fn [event on-load source]
41+
on-image-loaded (fn [event on-load]
4042
(when (fn? on-load) (on-load event))
4143
(reset! loaded? true)
42-
(reset! error? false)
43-
(reset! previous-source source))]
44+
(reset! error? false))]
4445
(fn [{:keys [source fallback-content on-error on-load] :as props}]
45-
[internal-fast-image
46+
[:> FastImage
4647
(assoc props
47-
:source (get-source source)
48-
:on-error #(on-image-error % on-error)
49-
:on-load #(on-image-loaded % on-load source))
50-
(cond
51-
@previous-source
52-
[internal-fast-image (assoc props :source (get-source @previous-source))]
53-
54-
(or @error? (not @loaded?))
48+
:source (build-source source)
49+
:on-error #(on-image-error % on-error)
50+
:on-load #(on-image-loaded % on-load))
51+
(when (or @error? (not @loaded?))
5552
[placeholder
56-
{:style (:style props)
53+
{:style (js->clj (:style props))
5754
:fallback-content fallback-content
5855
:error? @error?
5956
:loaded? @loaded?}])])))
57+
58+
(defn- compare-sources [old-props new-props]
59+
(let [old-source (oops/oget old-props :source)
60+
new-source (oops/oget new-props :source)]
61+
(and old-source
62+
new-source
63+
(= (remove-port old-source) (remove-port new-source)))))
64+
65+
(def fast-image
66+
(-> internal-fast-image
67+
(reagent/reactify-component)
68+
(rn/memo compare-sources)
69+
(reagent/adapt-react-class)))

0 commit comments

Comments
 (0)