【问题标题】:Problem with Autocomplete (Material UI + React + Reagent/ClojureScript)自动完成问题(Material UI + React + Reagent/ClojureScript)
【发布时间】:2021-01-04 17:14:15
【问题描述】:

我在使用 Material UI 的 Autocomplete 和 Reagent (ClojureScript) 时遇到问题。该元素呈现良好,但是当我尝试单击它时,出现以下异常:

Uncaught TypeError: Cannot read property 'focus' of null
    at handleClick (useAutocomplete.js:938)
    at HTMLUnknownElement.callCallback (react-dom.development.js:189)
    at Object.invokeGuardedCallbackImpl (react-dom.development.js:238)
    at invokeGuardedCallback (react-dom.development.js:293)
    at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:307)
    at executeDispatch (react-dom.development.js:390)
    at executeDispatchesAndReleaseTopLevel (react-dom.development.js:412)
    at forEachAccumulated (react-dom.development.js:3260)
    at runEventsInBatch (react-dom.development.js:3305)
    at handleTopLevel (react-dom.development.js:3515)

useAutocomplete.js:322 Uncaught TypeError: Cannot read property 'removeAttribute' of null
    at eval (useAutocomplete.js:322)
    at eval (useEventCallback.js:26)
    at eval (useAutocomplete.js:433)
    at eval (useEventCallback.js:26)
    at eval (useAutocomplete.js:463)
    at eval (useAutocomplete.js:528)
    at commitHookEffectListMount (react-dom.development.js:19765)
    at commitPassiveHookEffects (react-dom.development.js:19803)
    at HTMLUnknownElement.callCallback (react-dom.development.js:189)
    at Object.invokeGuardedCallbackImpl (react-dom.development.js:238)

在 JS 调试器中中断,我看到 inputRef.current 为空(这是调用 focusremoveAttribute 的原因。(奇怪的是,在文件中设置 inputRef 的唯一位置是通过调用useRef(null),这就是导致 inputRef.current 为空的原因。)

在我的代码中,我将自动完成字段定义如下:

(ns my-product-redacted.views.atoms
  (:require [reagent.core :as r]
            ["@material-ui/lab/Autocomplete" :default Autocomplete]
            ;; other requires
  ))

(def autocomplete-field (r/adapt-react-class Autocomplete))

那么,在一个 React 组件中,它是这样使用的:

[a/autocomplete-field {:render-input      (fn [js-params]
                                            (let [clj-params (js->clj js-params)
                                                  params     {:label             label
                                                              :width             width
                                                              :select            select?
                                                              :Input-label-props {:shrink true}
                                                              :Select-props      {:native true}}
                                                  all-params  (into clj-params params)]
                                               (js/console.log (clj->js all-params))
                                               (r/as-element [a/text-field all-params])))
                       :options          (when select? (cons {:value "" :label ""} options))
                       :get-option-label (fn [option] (or (get (js->clj option) "label") ""))
                       :default-value    (when (not select?) value-override)
                       :value            (when select? value)
                       :disabled         disabled?
                       :on-focus         #(re-frame/dispatch [::forms/on-focus path])
                       :on-blur          #(re-frame/dispatch [::forms/on-blur path])
                       :on-change        #(re-frame/dispatch (conj on-change (-> % .-target .-value)))})]

(这里,a/text-field 也与a/autocomplete-field 定义在相同的命名空间中,并且以类似的方式。)

JS 控制台日志(来自(js/console.log (clj->js params)) 调用)显示inputProps.ref.current 设置为空。但是,InputProps.ref 不为空。尽管如此,我还是尝试手动将与InputProps.ref 传递的相同函数关联到inputProps.ref.current,但这并没有什么区别。

我还尝试了https://github.com/mui-org/material-ui/issues/21245 中建议的解决方法(尽管该问题与格式塔库有关,而不是与试剂有关,但它表明引用转发可能存在问题)。但是将text-field 包装到一个div 中,其中ref 取自InputProps.ref 也没有任何区别。

有什么建议吗?

【问题讨论】:

    标签: reactjs autocomplete material-ui clojurescript reagent-forms


    【解决方案1】:

    在渲染输入 js 参数上调用 js->clj 会破坏它们。

    我在我的演示库 here 中放了一个材料 UI 自动完成组件的快速演示。

    但主要取自官方试剂文档/示例here

    (defn autocomplete-example []
      [:> mui/Grid
       {:item true}
       [:> Autocomplete {:options ["foo" "bar" "foobar"]
                         :style {:width 300}
                         ;; Note that the function parameter is a JS Object!
                         ;; Autocomplete expects the renderInput value to be function
                         ;; returning React elements, not a component!
                         ;; So reactify-component won't work here.
                         :render-input (fn [^js params]
                                         ;; Don't call js->clj because that would recursively
                                         ;; convert all JS objects (e.g. React ref objects)
                                         ;; to Cljs maps, which breaks them, even when converted back to JS.
                                         ;; Best thing is to use r/create-element and
                                         ;; pass the JS params to it.
                                         ;; If necessary, use JS interop to modify params.
                                         (set! (.-variant params) "outlined")
                                         (set! (.-label params) "Autocomplete")
                                         (r/create-element mui/TextField params))}]])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 2020-03-12
      • 2018-04-27
      • 2020-04-16
      • 2021-06-05
      • 2020-08-13
      相关资源
      最近更新 更多