0

作为一个 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!吞下事件?

4

1 回答 1

1

是的,这是必要的。每次状态更改时,DOM 都会重新渲染并清除您输入的值。因此,如果您的 's 属性中没有:value:input它将被清除。

原因是当 React.js 开始用虚拟 DOM 比较真实 DOM 时,它发现value真实属性中有一些,而虚拟 DOM 中没有,因此它清除它,假设这是你的想。您应该始终明确 DOM 应该是什么样子(例如,您的第二个片段)。

于 2015-09-15T10:00:08.640 回答