2016-12-23 15 views
0

Скажем, у меня есть компонент, определенный как это:Локальный атом реагент не будет обновляться, когда глобальное изменение ratom

(defn test-comp 
    [timespan-ratom] 
    (let [[timespan-lower timespan-upper] @timespan-ratom] 
    (fn [] 
     [:div.row (str "Testing" timespan-lower timespan-upper)]))) 

timespan-ratom определен глобально в компоненте, который создает test-comp так:

(def timespan-ratom (ratom nil)) 

Он создается таким образом:

[test-comp timespan-ratom] 

Впервые timespan-ratom используется для создания test-comp «Тестирование» будет напечатано с правильными значениями timespan-lower и timespan-upper. Но когда сбрасывается timespan-ratom (reset!), значения не обновляются в компоненте test-comp? Почему это?

Это работает, когда я изменить функцию следующим образом:

(defn test-comp 
    [timespan-ratom] 
    (fn [] 
     [:div.row (str "Testing" (first @timespan-ratom) (second @timespan-ratom))])) 

Теперь причина, почему я не могу просто сделать так, что в моем фактическом производстве код у меня есть местный ratom, который зависит от значения timespan-ratom:

(defn test-comp 
    [timespan-ratom] 
    (let [[timespan-lower timespan-upper] @timespan-ratom 
     selected-time (ratom timespan-upper)] 
    (fn [] 
     ,,,))) 

Т.е. Т.е. начальное значение selected-time должно быть значением timespan-upper, определяемым timespan-ratom. Затем ранец selected-time изменяется локально из компонента test-comp.

Как я могу это решить?

ответ

1

Снимите внутреннюю функцию гнездящихся из test-comp:

(defn test-comp 
    [timespan-ratom] 
    (let [[timespan-lower timespan-upper] @timespan-ratom] 
    [:div.row (str "Testing" timespan-lower timespan-upper)])) 

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

Если у вас есть локальное состояние (некоторое состояние, которое необходимо запомнить за время жизни компонента), обновите свой компонент, чтобы внутренняя функция имела те же аргументы, что и внешняя функция, и разыменовала атом во внутренней функции:

(defn test-comp 
    [ratom] 
    (let [x "local-state"] 
    (fn [ratom] 
     (let [v @ratom] 
     [:div x v])))) 
+0

Я не показывал внутреннее состояние в упрощенном примере, но у меня действительно есть внутреннее состояние, на которое влияет ратификация 'selected-time'. – Johan

+0

Затем вам нужно добавить тот же список аргументов внешней функции во внутреннюю функцию. Я отредактировал свой ответ соответственно. –

+1

Если внутреннее состояние, на которое влияет выбранный момент времени, является исключительно выводимым из этого числа, оно, однако, не является компонентом локального состояния. Это всего лишь одно или несколько значений, вычисленных для каждого рендеринга. Подробнее см. Https://github.com/Day8/re-frame/wiki/Creating-Reagent-Components. –