2017-12-19 16 views
1

I成分を有する:新しいpropsを試薬中のacomponentの状態に渡すには?

(defn inner-input [cljs_element activeEl title] 
    (let [form (atom title)] 
    (fn [cljs_element activeEl title] 
     [:input {:type "text" 
      :onChange #(reset! form (.. % -target -value)) 
      :on-blur #(change-title cljs_element (.. % -target -value)) 
      :style {:display (if (:active (:node cljs_element)) "block" "none") 
        :width (* (+ 1 (count @form)) 8) 
        :max-width 730 
        :min-width 170} 
      :value @form}]))) 

これは、他の構成要素にネストされている:

(defn card-input [cljs_element activeEl] 
    (fn [cljs_element activeEl] 
    (let [title (:title (:node cljs_element))] 
     [:div 
     [inner-input cljs_element activeEl title]]))) 

iは内側入力成分で入力データを入力すると、私は、ローカル状態を更新する必要フォーム。そして、外部コンポーネントカード入力の更新が私のフォームを新しいタイトルの議論から私のフォームをリセットしたい場合。どうすればそれを達成できますか?私が試した

インナー入力コンポーネントでのletとFNの間(reset! form title)を置くが、それはあなたが聞いて停止するように、タイトル、およびreagent/disposeへの変更を聞くことreagent/track!を使用することができます

+0

私があなたが 'render'関数の' form'アトムを更新する必要があることを覚えている限り、それは外部コンポーネントからの各レンダーコールの後に呼び出されるでしょう。 – leetwinski

+0

@leetwinskiの直後に '(fn [cljs_element activeEl title] ...)'の直後に '(reset!form title)'を追加する必要がありますが、この場合 '(reset!form title)'はlocalstateの変更を書き換えます:onChange外側のコンポーネントが更新されたときにのみ、引数からのフォームアトムをタイトルに変更する必要があります。 –

+0

あなたのレンダリング関数(リセット)は、外部コンポーネントの更新の場合にのみ呼び出されます。その後、変更ハンドラ – leetwinski

答えて

1

を助けにはなりません。代わりにadd-watchとremove-watchを使うこともできますが、トラックはもっと便利な構文です。

(defn inner-input [title] 
    (reagent/with-let 
    [form (reagent/atom @title) 
    watch (reagent/track! (fn [] (reset! form @title)))] 
    [:label 
    "Inner input" 
    [:input {:on-change (fn [e] 
          (reset! form (.. e -target -value))) 
       :on-blur (fn [e] 
         (reset! title (.. e -target -value))) 
       :value @form}]] 
    (finally 
     (reagent/dispose! watch)))) 

(defn card-input [] 
    (reagent/with-let 
    [title (reagent/atom "hello")] 
    [:div 
    [:label "Title" 
     [:input {:on-change (fn [e] 
          (reset! title (.. e -target -value))) 
       :value @title}]] 
    [inner-input title]])) 

あなたは、内側の入力に入力する場合は、入力ボックスを終了すると今では唯一の外側を更新しますが、外側のタイトルを変更すると、すぐ内側の1を変更します。それはあなたが望んだことですか?

タイトルをratomとして渡したくない場合は、それを値として渡す必要がある場合は、以前の値と比較して変更されているかどうかを判断し、変更されたときにのみフォームをリセットします。

(when (not= @previous-title title) 
    (do (reset! previous-title title) 
     (reset! form title))) 

このコードは、form変化が...何も起こりませんときに呼び出すことは安全であると見て、レンダリングで行くことができます。

+1

ありがとう!/create-class'マクロ。私はコードを書いた':component-did-update'キーの中のあなたの答えの2番目の変種と同様に、そのキーの下のコールバック関数は引数の中に以前の小道具を持っています –

関連する問題