我有一个文本输入元素,它使用组件状态和应用程序状态 .
在React: More About Refs中显示的示例中,目标是在重新渲染后在元素上调用 focus
. 这是关键部分,在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
,未显示,"cleans up"组件状态,以便它适合应用程序状态 . )
更改文本输入的组件状态不会导致它失去焦点,但会改变应用程序状态 .
我已经尝试过使用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!
) .
1 回答
一个潜在的解决方案是在你的om / root调用中使用core.async和
:tx-listen
.:tx-listen
选项允许您指定在提供的应用程序状态更改时要调用的函数 - 因此我们提供一个函数,该函数写入附加了'pub'的通道 .然后,当您的组件安装时,您使用
IWillMount
订阅该通道上的事件,并在IWillUnmount
上清除它 .显然,这里有一些清理的空间(特别是,您可能希望缩小组件所听取的事件类型) - 但它展示了基本的想法 .
然后 - 在组件代码中,您可以订阅mount上的更改,并在卸载时关闭通道