Fork me on GitHub
#reagent
<
2024-04-08
>
erwinrooijakkers15:04:30

Hi all, I am trying to wrap my reagent root in a https://github.com/authts/react-oidc-context? as such using shadow-cljs:

(ns core
  (:require
   [react-oidc-context :as oidc]
   [reagent.dom]))

(def oidc-config
  #js {:authority ""
       :client_id "my-client"
       :redirect_uri ""})

(defn main-panel []
  [oidc/AuthProvider oidc-config
   [app]])

(defn root []
  [:f> main-panel])

(defn ^:dev/after-load mount-root []
  (re-frame/clear-subscription-cache!)
  (re-frame/dispatch-sync [::events/initialize-db])
  (reagent.dom/render [root]
                      (.getElementById js/document "app")))

(defn ^:export init []
  (mount-root))
This throws the error > react-dom.development.js:16228 > Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: > 1. You might have mismatching versions of React and the renderer (such as React DOM) > 2. You might be breaking the Rules of Hooks > 3. You might have more than one copy of React in the same app > See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. > at Object.throwInvalidHookError (react-dom.development.js:16228:13) > at exports.useState (react.development.js:1623:21) > at cmp.AuthProvider [as reagentRender] (react-oidc-context.js:156:25) > at eval (component.cljs:88:28) > at Object.reagent$impl$component$wrap_render [as wrap_render] (component.cljs:91:31) > at Object.reagent$impl$component$do_render [as do_render] (component.cljs:117:6) > at eval (component.cljs:260:64) > at Object.reagent$ratom$in_context [as in_context] (ratom.cljs:44:6) > at Object.reagent$ratom$deref_capture [as deref_capture] (ratom.cljs:57:14) > at Object.reagent$ratom$run_in_reaction [as run_in_reaction] (ratom.cljs:539:14) Is this possible to get this library to work? Any suggestions on how to fix? Goal is to get PKCE flow to work with Reagent and Keycloak.

p-himik15:04:48

That :f> is unnecessary because main-panel doesn't have anything that necessitates it being a function component. When using oidc/AuthProvider, you should prefix it with :> since it's a React component:

(defn main-panel []
  [:> oidc/AuthProvider oidc/config
    [app]])

erwinrooijakkers15:04:49

:face_palm: thanks of course

erwinrooijakkers15:04:58

No more warnings, still doesn’t work but this was the main culprit 🙂 long day 😉

👍 1
erwinrooijakkers15:04:15

I actually did need to wrap the use of the library in a function component. This works:

(ns views
 (:require [react-oidc-context :refer [useAuth]]))

(defn auth-wrapper []
  (let [auth (useAuth)]
    (cond (.-isLoading auth) [:div "Loading..."]
          (.-error auth) [:div "Error"]
          (.-isAuthenticated auth) [main-panel]
          :else (.signinRedirect auth))))

(defn root []
  [:f> auth-wrapper])

;; core:

(reagent.dom/render
   [:> AuthProvider oidc-config
    [views/root]]
   (.getElementById js/document "app"))