You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

reagent/atom在REPL中的行为疑问及报错原因咨询

Why does passing a dereferenced Reagent atom to my component cause an error?

Let's break down exactly what's happening here—this issue boils down to a mismatch between what your function expects and what you're passing it.

First, look at the core of your project-board function:

(defn project-board [app-state project-id]
  (into [:ul]
        (for [[id {:keys [title]}] (get-in @app-state [:projects project-id :stories])]
          [:li title])))

Notice the @app-state inside the function? That's shorthand for (deref app-state), which only works if the value passed as app-state implements the IDeref protocol. Reagent atoms (like your app-state variable) are built for this—they're state containers that let you dereference to get their internal data.

Here's the play-by-play for each call:

  • When you run (project-board app-state "aaa"): You're passing the actual atom instance. The @app-state in the function dereferences it correctly to pull out the underlying map, so everything runs smoothly.
  • When you run (project-board @app-state "aaa"): You're passing the dereferenced value of the atom, which is just a plain cljs.core/PersistentArrayMap. Regular ClojureScript maps don't implement the IDeref protocol—they're just static data—so trying to do @app-state on a map throws that "No protocol method IDeref.-deref defined" error.

How to fix this

You have two simple options, depending on how you want to design your component:

  1. Adjust the function to accept plain data (not atoms)
    If you want to pass dereferenced state to the component, remove the @ from inside the function so it works directly with the map:

    (defn project-board [projects-data project-id]
      (into [:ul]
            (for [[id {:keys [title]}] (get-in projects-data [:projects project-id :stories])]
              [:li title])))
    

    Now (project-board @app-state "aaa") will work perfectly, since you're operating directly on the raw map data.

  2. Keep the function designed for atoms (recommended for Reagent components)
    Reagent components often expect atoms because this lets them auto-re-render when the atom's state changes. If you want to retain this reactive behavior, just stick to passing the atom itself like (project-board app-state "aaa")—this is the standard pattern for stateful Reagent components.

In short: The error happens because you're trying to dereference a plain map, which isn't a dereferenceable type. Your function's code expects an atom, so either pass an atom or tweak the function to work with raw data instead.

内容的提问来源于stack exchange,提问作者mwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:37:37