让子组件对父母的州加上自己的状态作出反应

时间:2017-02-18 07:09:40

标签: clojurescript reagent

考虑以下Reagent组件:

(defn sub-compo [n]
  (let [state (r/atom {:colors (cycle [:red :green])})]
    (fn []
      [:div {:style {:color (-> @state :colors first)}
             :on-mouse-move #(swap! state update :colors rest)}
       "a very colorful representation of our number " n "."])))

(defn compo []
  (let [state (r/atom {:n 0})]
    (fn []
      [:div {:on-click #(swap! state update :n inc)}
       "Number is " (@state :n) "."
       [sub-compo (@state :n)]])))

我试图构建一个示例,其中子组件应该依赖于其父组件的状态。但是,子组件也应该具有内部状态。以上不能正常工作。如果compo更改sub-compo中的状态未初始化为新的。

为了让sub-compocomp保持同步,将采用哪种方法?每当comp更改状态sub-comp实际上应该重新初始化时,意味着它的颜色状态再次设置为初始值。

这是一个至少能满足我想要的解决方案。它使用光标和手表。但也许有一种更简单的方法,无论如何:

(defn sub-compo [n]
  (let [init-state {:colors (cycle [:red :green])}
        state (r/atom init-state)]
    (add-watch n :my (fn []
                       (reset! state init-state)))
    (fn []
      [:div {:style {:color (-> @state :colors first)}
             :on-mouse-move #(swap! state update :colors rest)}
       "a very colorful representation of our number " @n "."])))

(defn compo []
  (let [state (r/atom {:n 0})]
    (fn []
      [:div {:on-click #(swap! state update :n inc)}
       "Number is " (@state :n) "."
       [sub-compo (r/cursor state [:n])]])))

1 个答案:

答案 0 :(得分:0)

  

以上操作无效。当compo中的状态发生变化时   sub-compo未初始化为新的。

这是因为sub-compo的内部函数也需要接收参数n

  

每当comp的状态改变sub-comp时实际应该是   重新初始化,意味着它的颜色状态被设置为初始值   试。

您可以使用:component-will-receive-props

这对我有用:

(defn sub-compo [n]
  (let [init {:colors (cycle [:red :green])}
        state (r/atom init)]
    (r/create-class
     {:component-will-receive-props
      (fn [this [_ n]]
        (reset! state init))
      :reagent-render
      (fn [n]
        [:div {:style {:color (-> @state :colors first)}
               :on-mouse-move #(swap! state update :colors rest)}
         "a very colorful representation of our number " n "."])})))