Почему db печатает #object [Object [object Object]] в рефрейме? - PullRequest
1 голос
/ 03 марта 2020

В следующем коде я отправляю два события щелчка мышью:

;; event
(reg-event-db
 :some
 (fn [db [_ some-val]]
   (prn "The db is" db)
   (assoc db :some some-val)
   ))

;; another event
(reg-event-db
 :another
 (fn [db [_ another-val]]
   (prn "The db is" db)
   (assoc db :another another-val)
   ))

;; button
[:input {:type "button" :value "Button"
         :on-click #(do
                       (dispatch [:some :some-val])
                       (dispatch [:another :another-val]))}]

Но вместо печати карты БД она печатает "The db is" #object[Object [object Object]], а затем

Error: No protocol method IAssociative.-assoc defined for type object: [object Object]

Что я делаю неправильно? Я также попытался сделать #(dispatch [:some :some-val :another another-val], но это дало ту же ошибку. В общем, как правильно отправить два события?

1 Ответ

0 голосов
/ 06 марта 2020

Это правильно:

(do
  (dispatch [:first-event :some-value])
  (dispatch [:second-event :other-value]))

Это не правильно:

(dispatch [:some :some-val :another another-val])

В этом примере вы отправляете одно событие с 3 аргументами:

  • :some - имя события,
  • :some-val - первый аргумент,
  • :another - второй аргумент,
  • another-val является третьим аргументом.

Ошибка, с которой вы сталкиваетесь, связана не с вашими dispatch событиями, а с вашим состоянием db. Давайте разберем его шаг за шагом:

Если (prn db) выводит #object[Object [object Object]], это означает, что db является JavaScript объектом.

Если (assoc db …) завершается с No protocol method IAssociative.-assoc defined for type object: [object Object], это означает, что значение db не поддерживает функцию assoc. Функция assoc определяется протоколом (интерфейс Think), и этот протокол реализован на картах. Итак, здесь db не является картой.

Почему db будет JavaScript объектом вместо карты Clojure?

Когда вы используете (reg-event-db :event-name handler-function), значение, возвращаемое handler-function, заменит состояние db. Если по ошибке вы вернете объект JS, он станет новым значением db, и это новое неправильное значение db будет передано последующим обработчикам событий. Поэтому весьма вероятно, что один из ваших обработчиков событий вернет объект JavaScript.

Как я мог бы решить эту ситуацию:

  • использовать (js/console.log db) вместо (prn db). Вы сможете увидеть, что находится внутри этого js объекта. prn не знает, как правильно печатать js объекты.
  • убедитесь, что cl js -devtools установлен и работает. Позволяет исследовать сложные объекты в консоли. В следующий раз, когда возникнет эта проблема, вы сразу увидите значение проблемного c вместо непрозрачного строкового представления.
  • используйте reg-event-fx вместо reg-event-db. Будучи немного более многословным, он покажет человеческому глазу, какое значение вы вкладываете в db.
  • Если вы хотите go продолжить и убедиться, что это никогда не повторится, взгляните на Re-Frame Middlewares . В вашем случае промежуточное ПО позволит вам работать с возвращенными значениями обработчиков и потенциально отклонять его, если оно не соответствует вашим ожиданиям.
...