2017-08-03 6 views
0

this postをClojurescriptの試薬で熟読すると、timer-componentコンポーネントを実装するさまざまな方法で実験しました。私の最初の試みは、しかし、動作しませんでした:成分が試薬で正しく表示されないのはなぜですか?

(defn timer-component [] 
    (fn [] 
    (let [seconds-elapsed (r/atom 0)] 
     (js/setTimeout #(swap! seconds-elapsed inc) 1000) 
     [:p (str "Expired time: " @seconds-elapsed)]))) 

デバッグログステートメントは、タイマーがまだ定期的に呼び出され、seconds-elapsed変数がまだ正しく更新されて明らかにしたよう。ただし、表示は更新されず、コンポーネントには常に「有効期限:0」が表示されます。ブログでのコード例に比べ

は私のコンポーネントを投稿fnを入れ替えるとlet宣言と、この変更は、適切な表示を防ぐように見えるが、コンポーネントのない適切なアップデート。私の期待は、コンポーネントが正しく更新されて表示されるか、更新も表示もされないということでした。

私の質問はなぜこれが起こるのですか?これはReagentのバグか、APIの誤用ですか?

答えて

2

すべての(再)レンダリングに対して内部無名関数が呼び出されているため、常に同じ値が表示されます。したがって、seconds-elapsedは値0の新しいアトムに何度も繰り返しバインドされています。これはバグではありませんが、Reagentはどのように動作するのでしょうか。

あなたのコンポーネントは "Form-2"であり、外部関数timer-componentでローカル状態を宣言する必要があります。これはコンポーネントごとに1回だけ呼び出されます。 Re-frame documentation explains different forms of Reagent components

再フレームのドキュメントを明確にするために役立つかもしれ試薬のチュートリアル、例にコメントを追加

(defn timer-component [] 
    (let [seconds-elapsed (reagent/atom 0)]  ;; setup, and local state 
    (fn []  ;; inner, render function is returned 
     (js/setTimeout #(swap! seconds-elapsed inc) 1000) 
     [:div "Seconds Elapsed: " @seconds-elapsed]))) 
関連する問題