Skip to content

Instantly share code, notes, and snippets.

@raspasov
Last active March 14, 2017 10:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raspasov/e9a1008f2c0d5be2d202f0a4cdebe009 to your computer and use it in GitHub Desktop.
Save raspasov/e9a1008f2c0d5be2d202f0a4cdebe009 to your computer and use it in GitHub Desktop.
VirtualizedList + Om.next
(ns immutable-v-list
"Example of React Native VirtualizedList from Om.next"
(:require [om.next :as om :refer-macros [defui]]))
(set! js/window.React (js/require "react"))
(set! js/window.ReactNative (js/require "react-native"))
(def ^js/window.ReactNative ReactNative js/window.ReactNative)
(defn create-element-no-auto-js
"Creates an element without auto-converting opts via (cljs->js opts).
Needed for VirtualizedList, et al"
[rn-component opts & children]
;remove :data from opts so we don't convert it uselessly to JS objects
(let [js-opts (clj->js (dissoc opts :data))
data (get opts :data)]
;add "data" back to the JS object as an immutable Clojure structure
(aset js-opts "data" data)
(apply js/React.createElement rn-component js-opts children)))
;VirtualizedList
(def virtualized-list (partial create-element-no-auto-js (.-VirtualizedList ReactNative)))
(defui ImmutableVList
Object
(render [this]
(virtualized-list
{:style (get (om/props this) :style {})
:data (get (om/props this) :data [])
;return tuple [item-data idx] - idx needed for keyExtractor
;item-data is Clj data (usually a map)
:getItem (fn [data idx]
(let [item-data (nth data idx nil)]
[item-data idx]))
:getItemCount (fn [data] (count data))
;needs to return a key as string
:keyExtractor (fn [[_ idx]] (str idx))
:renderItem (fn [^js/Object js-object]
(let [[item-data _] (.-item js-object)
idx (.-index js-object)
render-item (om/get-computed this :render-item)]
(render-item item-data idx)))})))
(def immutable-v-list (om/factory ImmutableVList))
;USAGE
;======================================================================================================================
;given a vector of products...
(let [products [{:p 1} {:p 2} {:p 3}]]
;... display them in VirtualizedList view
(immutable-v-list
;pass our own render-item function via om/computed
(om/computed
;props
{:data products
;any React Native style
:style {}}
;computed
{:render-item
(fn [product idx]
;product is {:p 1} or {:p 2}, etc on each item render
;render any valid Om/React component as usual
;note: my-row-item component not provided in this example
(my-row-item product))})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment