我有一个使用组件状态和应用程序状态的文本输入元素。
在React: More About Refsfocus
中显示的示例中,目标是在重新渲染后调用元素。这是关键部分,用 React 中的 JS 完成。
clearAndFocusInput: function() {
// Clear the input
this.setState({userInput: ''}, function() {
// This code executes after the component is re-rendered
this.refs.theInput.getDOMNode().focus(); // Boom! Focused!
});
},
我想对Om做类似的事情。我也没注意到
提供了指定回调的方法。所以我正在寻找其他方法来在重新渲染后导致某些事情发生。
这是我的例子:
(defn input-component
[{:keys [app-state-key class-name]}]
(fn [data owner]
(reify
om/IInitState
(init-state
[this]
{:text (data app-state-key)})
om/IRenderState
(render-state
[this state]
(let [handle-change (handle-change-fn data app-state-key)]
(dom/input
#js {:ref (name app-state-key)
:type "text"
:className class-name
:value (:text state)
:onChange #(handle-change % owner state)}))))))
(defn handle-change-fn
[app-state app-state-key]
(fn [e owner state]
(let [element (.-target e)
value (.-value element)]
(om/set-state! owner :text value)
(if-let [value' (parse-int value)]
(om/update! app-state app-state-key value')))))
(注意:parse-int
未显示,“清理”组件状态,使其适合应用程序状态。)
更改文本输入的组件状态不会导致它失去焦点,但改变应用程序状态会。
我尝试过使用 core.async 通道,但这似乎没有帮助,因为我只希望在重新渲染完成后发生回调。
我也尝试过使用IDidUpdate
,像这样:
(defn input-component
[{:keys [app-state-key class-name]}]
(fn [data owner]
(reify
; ...
om/IDidUpdate
(did-update
[this prev-props prev-state]
(let [e (om/get-node (.-owner this))]
(.log js/console "did-update" e)
(.focus e)))
; ...
)))
更新:如果仅更新组件状态,IDidUpdate
生命周期事件就会触发。om/update!
但是,如果应用程序状态发生变化(由于上述原因),它不会触发。