Skip to content

Instantly share code, notes, and snippets.

@seantempesta
Last active December 5, 2022 08:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save seantempesta/8b01e71148d9b01f8591d083926e2c89 to your computer and use it in GitHub Desktop.
Save seantempesta/8b01e71148d9b01f8591d083926e2c89 to your computer and use it in GitHub Desktop.
(defn virtualized-list
"Reagent version of VirtualizedList
https://facebook.github.io/react-native/releases/0.43/docs/virtualizedlist.html
props = Map with at least :data and :renderItem specified
:data = A vector (or list I suppose) with whatever you want passed to each row
:renderItem = A fn that accepts a map with two keys {:item row-data, :index row-number} and returns a reagent vector.
Ex. [virtualized-list {:data [{:a 1} {:a 2}]
:renderItem (fn [{:keys [item index]}]
[:> Text {} (:a item)])}]]]]))
"
[props]
(fn [{:keys [data renderItem] :as props}]
(assert data ":data key must be specified")
(assert (fn? renderItem) ":renderItem fn must be specified")
(let [clj-fns {:getItem nth
:getItemCount count
:keyExtractor #(str %2)
:renderItem #(r/as-element (renderItem {:item (aget % "item")
:index (aget % "index")}))}
dissoc-props (apply dissoc props [:data :renderItem])
merged-props (merge clj-fns dissoc-props)
merged-props-js (clj->js merged-props)
_ (aset merged-props-js "data" data)]
(r/create-element VirtualizedList merged-props-js))))
;; Example using it
;; You just need to pass in :data and a :renderItem fn
(def simple-component []
(fn []
[:> View {:flex 1}
[virtualized-list {:data [{:a 1} {:a 2}]
:renderItem (fn [{:keys [item index]}]
[:> Text {} (:a item)])}]]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment