Как распространять текст во вводе onChange с помощью React/Om

Как новичок в React/Om, я не уверен, что эта проблема специфична для Om.

Я хочу создать компонент ввода даты на основе ввода произвольного текста. Он включает поле <input>, где они могут вводить текст, и поле <p>, отображающее проанализированную дату (если она действительна).

Я реализовал это как:

(defn parse-date [e owner]
  (let [text (.. e -target -value)]
    (om/set-state! owner :parsed-date text)))

(defn date-entry [app owner]
  (reify
    om/IInitState
    (init-state [_] {:parsed-date ""})
    om/IRenderState
    (render-state [this state]
      (dom/div nil
               (dom/input #js {:type "text" 
                               :ref "date"
                               :id "new-date"
                               :onChange #(parse-date % owner)})
               (dom/p     nil (:parsed-date state))))))

К сожалению, как только я подключаю этот обработчик изменений, он ведет себя не так, как ожидалось. Когда я набираю цифру в поле ввода, я вижу, что она появляется в поле ввода и <p> рядом с ней, но затем она сразу же исчезает из ввода.

Я могу обойти это, поместив текст в состояние:

(defn parse-date [e owner]
  (let [text (.. e -target -value)]
    (om/set-state! owner :parsed-date text)
    (om/set-state! owner :text text)))

(defn date-entry [app owner]
  (reify
    om/IInitState
    (init-state [_] {:parsed-date "" :text ""})
    om/IRenderState
    (render-state [this state]
      (dom/div nil
               (dom/input #js {:type "text" 
                               :ref "date" 
                               :id "new-date" 
                               :onChange #(parse-date % owner) 
                               :value (:text state)})
               (dom/p     nil (:parsed-date state))))))

Однако я удивлен, что мне пришлось это сделать. Это действительно необходимо? Может кто-нибудь объяснить, что здесь происходит, или указать мне соответствующие документы? Почему подключение обработчика изменений, вызывающего set-state!, поглощает событие?


person Konrad Garus    schedule 12.09.2015    source источник


Ответы (1)


Да, это необходимо. Каждый раз, когда состояние изменяется, DOM перерисовывает и очищает введенное вами значение. Поэтому, если у вас нет :value в атрибутах :input, он будет очищен.

Причина этого в том, что когда React.js начинает сравнивать реальный DOM с виртуальным, он обнаруживает, что в реальном атрибуте есть value, а в виртуальном DOM его нет, и поэтому он очищает его, предполагая, что это то, что ты хочешь. Вы всегда должны четко указывать, как должен выглядеть DOM (например, ваш второй фрагмент).

person skrat    schedule 15.09.2015