Могу ли я использовать (если) в качестве функции визуализации реагента формы-2 - PullRequest
0 голосов
/ 02 июля 2019

Я использую условие (если) в качестве функции отображения формы-2 следующим образом:

(defn bro [dex]
      (let [yo (inc dex)]
           (if true
               [:div (str yo)])))

вместо этого:

(defn bro [dex]
      (let [yo (inc dex)]
           (fn [dex]
               (if true
                   [:div (str yo)]))))

Это проблема, если я использую оператор (if) вместо функции (fn)? А что происходит, когда утверждение становится ложным? Функция рендеринга возвращает ноль?

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

Нет, это не сработает, как вы ожидаете. Чтобы понять разницу, рассмотрим следующие два компонента:

(defn test-component-if []
  (let [a (atom 1)
        _ (.log js/console "let in -if")]
    (if (odd? @a)
      [:div
       [:p "odd"]
       [:button {:on-click #(swap! a inc)}
        "inc"]]
      [:div
       [:p "even"]
       [:button {:on-click #(swap! a inc)}
        "inc"]])))

(defn test-component-fn []
  (let [a (atom 1)
        _ (.log js/console "let in -fn")]
     ;; I dub thee test-inner
    (fn []
      (if (odd? @a)
        [:div
         [:p "odd"]
         [:button {:on-click #(swap! a inc)}
          "inc"]]
        [:div
         [:p "even"]
         [:button {:on-click #(swap! a inc)}
          "inc"]]))))

test-component-fn работает как положено, а test-component-if - нет. Это почему? Хорошо, когда компонент реагента может возвращать одну из двух вещей (я игнорирую компоненты типа 3, так как это влияет на знание реакции). Может вернуть

  1. вектор
  2. другая функция

Если он возвращает вектор, сама функция становится функцией рендеринга, в нашем случае test-component-if. Когда он возвращает функцию, функция, которая была возвращена, а не исходная функция, является функцией рендеринга. В этом случае, что я назвал test-inner

Когда Reagent вызывает функцию рендеринга, он отслеживает атомы, к которым обращается функция, и всякий раз, когда этот атом изменяется, он вызывает функцию рендеринга. Так что же происходит, когда мы используем test-component-if?

  1. Реагентные вызовы test-component-if
  2. Наш оператор let связывает новый атом a с 1.
  3. Вектор возвращается
  4. нажимаем на кнопку
  5. Атом a увеличивается
  6. Реагент видит изменение на a и звонит test-component-if
  7. В нашем предложении let связывается новый атом a с 1 (атом, отличный от нашего предыдущего a)
  8. по электронной почте Ой!

Так что a всегда 1. Вы можете убедиться в этом, посмотрев на консоль и увидев, что сообщение печатается каждый раз, когда вы нажимаете кнопку.

А как насчет test-component-fn?

  1. Реагентные вызовы test-component-fn
  2. Наш оператор let связывает новый атом a с 1.
  3. test-component-fn возвращает test-inner , который закрывается на a
  4. Реагентные вызовы test-inner
  5. Нажимаем на кнопку
  6. a увеличивается
  7. Реагент видит изменение на a и звонит test-inner
  8. Повторите столько раз, сколько вы хотите.

Вы можете проверить, что let выполняется еще раз на консоли. Нажмите на кнопку столько раз, сколько вы хотите, сообщение будет напечатано только при первом его отображении.

В терминах if без предложения else это действительно вернет ноль. В таких случаях принято использовать , когда вместо if, что дает понять, что подразумевается отсутствие else. Он также имеет преимущество включения неявного do . Что касается того, что будет делать Реагент, когда он обнаружит, что nil, в большинстве случаев он будет молча удалять его и ничего не отображать .

0 голосов
/ 02 июля 2019

Является ли проблема, если я использую оператор (if) вместо (fn) функции?

Я думаю, вы хотели использовать if внутри функция fn, но в любом случае это не проблема.

И что происходит, когда утверждение становится ложным?Функция рендеринга возвращает nil?

Реагент обрабатывает эти изящно, nil будет пропущен (соответствующий дочерний элемент не создан).Если вы увидите пример приложения TODO в официальных документах, то увидите, что исходный код имеет следующий код:

(when (pos? done)
       [:button#clear-completed {:on-click clear-done}
        "Clear completed " done])]))

В этом случае, если done не является положительнымчисло, возвращаемое значение этого выражения nil и кнопка для очистки завершенных задач просто не добавляется в DOM.

...