经常在 Cider 中看到 "REPL command timed out" with shadow-cljs 和 React Native。必须重启模拟器才能修复
Often seeing "REPL command timed out" in Cider with shadow-cljs and React Native. Must restart emulator to fix
我正在使用带有 Cider 和 ShadowCLJS 的 Emacs 来开发一个基本的 ReactNative 应用程序。我可以非常一致地使用 REPL 进行开发,但是一旦我不小心保存了一个有语法错误的文件,我就会失去与 REPL 的通信。我键入的任何内容都会导致延迟,然后是 "REPL command timed out"。我发现修复它的唯一方法是使用 npx react-native run-android
重新启动模拟器。但是后来我失去了我在 REPL 中的所有状态。
这可能是许多不同的事情。
这可能与 Metro(或 Expo)提供的实时加载有关。在模拟器中按 Ctrl-M(Mac 上的 Cmd-M)调出关闭快速刷新的选项。
https://facebook.github.io/react-native/docs/fast-refresh
https://github.com/thheller/shadow-cljs/issues/469
如果禁用快速刷新后仍然出现此错误,可能是因为 ReactNative 在重新加载时没有完全断开旧的 websockets。这是 shadow-cljs 创建者的评论。
its a bug in react-native in that it doesn't disconnect websockets when reloading the app so shadow-cljs thinks the "old" app is still running and tries talking to it (but it never replies) I opened an issue on the RN repo but it was closed due do inactivity for a year or so. nobody cared I guess.
我找到了使用 ReactNative 的 AppState 和从 shadow-cljs dev 命名空间引用 websocket 的解决方法。
https://facebook.github.io/react-native/docs/appstate.html
(defn on-app-state-change
"Fixes issue with shadow-cljs repl losing connection to websocket.
Put this in some root component's `component-did-mount`.
"
[state]
(cond
(= state "background")
(.close @shadow-rn/socket-ref)
(and (= state "active")
(nil? @shadow-rn/socket-ref))
(shadow-rn/ws-connect)))
(defn make-reloader
[component]
(let [component-ref (r/atom component)]
(letfn [(render []
(let [component @component-ref]
(if (fn? component)
(component)
component)))]
(let [wrapper (r/create-class
{:render render
:component-did-mount
(fn []
(.addEventListener rn/AppState "change" on-app-state-change))
:component-will-unmount
(fn []
(.removeEventListener rn/AppState "change" on-app-state-change))})]
(rn/AppRegistry.registerComponent "Ezmonic" (fn [] wrapper))
(fn [comp]
(reset! component-ref comp))))))
我正在使用带有 Cider 和 ShadowCLJS 的 Emacs 来开发一个基本的 ReactNative 应用程序。我可以非常一致地使用 REPL 进行开发,但是一旦我不小心保存了一个有语法错误的文件,我就会失去与 REPL 的通信。我键入的任何内容都会导致延迟,然后是 "REPL command timed out"。我发现修复它的唯一方法是使用 npx react-native run-android
重新启动模拟器。但是后来我失去了我在 REPL 中的所有状态。
这可能是许多不同的事情。
这可能与 Metro(或 Expo)提供的实时加载有关。在模拟器中按 Ctrl-M(Mac 上的 Cmd-M)调出关闭快速刷新的选项。
https://facebook.github.io/react-native/docs/fast-refresh
https://github.com/thheller/shadow-cljs/issues/469
如果禁用快速刷新后仍然出现此错误,可能是因为 ReactNative 在重新加载时没有完全断开旧的 websockets。这是 shadow-cljs 创建者的评论。
its a bug in react-native in that it doesn't disconnect websockets when reloading the app so shadow-cljs thinks the "old" app is still running and tries talking to it (but it never replies) I opened an issue on the RN repo but it was closed due do inactivity for a year or so. nobody cared I guess.
我找到了使用 ReactNative 的 AppState 和从 shadow-cljs dev 命名空间引用 websocket 的解决方法。
https://facebook.github.io/react-native/docs/appstate.html
(defn on-app-state-change
"Fixes issue with shadow-cljs repl losing connection to websocket.
Put this in some root component's `component-did-mount`.
"
[state]
(cond
(= state "background")
(.close @shadow-rn/socket-ref)
(and (= state "active")
(nil? @shadow-rn/socket-ref))
(shadow-rn/ws-connect)))
(defn make-reloader
[component]
(let [component-ref (r/atom component)]
(letfn [(render []
(let [component @component-ref]
(if (fn? component)
(component)
component)))]
(let [wrapper (r/create-class
{:render render
:component-did-mount
(fn []
(.addEventListener rn/AppState "change" on-app-state-change))
:component-will-unmount
(fn []
(.removeEventListener rn/AppState "change" on-app-state-change))})]
(rn/AppRegistry.registerComponent "Ezmonic" (fn [] wrapper))
(fn [comp]
(reset! component-ref comp))))))