Fork me on GitHub
#reagent
<
2020-12-27
>
Neros00:12:07

Hey people, hope Christmas went well. I am trying to get React QR Scanner to work in shadow-cljs and am having problems getting it working. I converted the following react code:

Neros00:12:13

import React, { Component } from 'react'
import QrReader from 'react-qr-scanner'

class Example extends Component {
  constructor(props){
    super(props)
    this.state = {
      delay: 500,
      result: 'No result',
    }

    this.handleScan = this.handleScan.bind(this)
  }
  handleScan(result){
    if(result){
      this.setState({ result })
    }
  }
  handleError(err){
    console.error(err)
  }
  render(){
    const previewStyle = {
      height: 240,
      width: 320,
    }

    return(
      <div>
        <QrReader
          delay={this.state.delay}
          style={previewStyle}
          onError={this.handleError}
          onScan={this.handleScan}
          />
        <p>{this.state.result}</p>
      </div>
    )
  }
}

Neros00:12:23

I converted it from class to functional in react then converted it to cljs: (defn example [] (let [state (r/atom {}) preview-style {:height "240" :width "320"}] [:<> (fn [] [:div [:> QrReader {:name "qr-reader" :delay (:qr-reader @state) :style preview-style :on-error (fn [e] (prn "You have an Error Bitch!")) :on-scan (fn [e] (swap! state assoc :qr-reader (-> e .-target .-value)))}]])])) I had made a few variations of the above and keep running into issues, any suggestions would be most welcome

p-himik04:12:28

Try removing the fragment and the lambda - return just the div Hiccup. Also log the value of QrReader to make sure that you've required it correctly.

Neros05:12:07

thanks I will check now

tomrbowden06:12:37

This works:

(ns qr.app.core
  (:require [reagent.core :as r]
            [reagent.dom :as rdom]
            ["react-qr-scanner" :as QrReader]))

(defn app []
  (let [state (r/atom {:delay  100
                       :result "No result"})
        preview-style {:height 240
                       :width  320}
        handle-error #(.error js/console %)
        handle-scan (fn [data]
                      (swap! state assoc :result data))
        _ (.dir js/console QrReader)]
    (fn []
      [:div
       [:> QrReader/default
        {:delay (:delay @state)
         :style preview-style
         :on-error handle-error
         :on-scan handle-scan}]
       [:p (:result @state)]])))

(defn render []
  (rdom/render [app] (.getElementById js/document "root")))

(defn ^:export main []
  (render))

tomrbowden07:12:41

Calling [:> QrReader/default ...] is a bit ugly, so you could require ["react-qr-scanner" :as QrReader :rename {default Scanner}], and then call the QR Scanner as [:> Scanner]

David Pham21:12:02

Someone implemented the components as keywords approach: https://github.com/pink-gorilla/pinkie