2016-10-13 8 views
5

मैं प्रतिक्रिया + रेडक्स सीख रहा हूं और मुझे एनिमेशन करने का उचित तरीका समझ में नहीं आता है। उदाहरण के लिए बोलें:रेडक्स/फ्लक्स (रीएक्टजेएस के साथ) और एनीमेशन

उदाहरण के लिए, मेरे पास एक सूची है और मैं क्लिक पर आइटम को हटाना चाहता हूं। अगर मेरे पास कोई एनीमेशन प्रभाव नहीं है तो यह बहुत आसान है: REMOVE_ITEM पर क्लिक करें, क्लिक करने पर कार्रवाई, reducer स्टोर से आइटम को हटा देता है और पुनः प्रस्तुत करता है एचटीएमएल।

चलिए क्लिक पर लाइन आइटम को हटाने का एनीमेशन जोड़ें। इसलिए, जब उपयोगकर्ता किसी आइटम पर क्लिक करता है तो मैं लाइन आइटम हटाने का एक फैंसी प्रभाव चलाने के लिए चाहता हूं और ... कैसे? मैं कई मायनों में यह कैसे करना है के बारे में सोच सकते हैं:

1) पर क्लिक करने पर मैं REMOVE_ITEM कार्रवाई प्रेषण, तो कम करने स्टोर में goingToBeDeleted के रूप में एक आइटम चिह्नित करते हैं, तो प्रतिक्रिया .fancy-dissolve-animation के एक वर्ग के साथ उस तत्व renders और मैं एक टाइमर चलाने दूसरी कार्रवाई REMOVE_ITEM_COMPLETED प्रेषित करने के लिए। मुझे यह विचार पसंद नहीं है, क्योंकि यह अभी भी अस्पष्ट है कि जेएस एनिमेशन कैसे जोड़ना है (उदाहरण के लिए, TweenMax के साथ) और जब मैं सीएसएस एनीमेशन समाप्त होता हूं तो मैं फिर से प्रस्तुत करने के लिए जेएस टाइमर चलाता हूं। अच्छा नहीं लगता है।

2) मैं ~ 30ms के अंतराल के साथ ITEM_REMOVE_PROGRESS क्रियाएं भेजता हूं, और स्टोर में कुछ "मान" होता है जो एनीमेशन की वर्तमान स्थिति का प्रतिनिधित्व करता है। मुझे यह भी पसंद नहीं है, क्योंकि मुझे एनीमेशन के ~ 2 सेकंड के लिए ~ 120 बार स्टोर की प्रतिलिपि बनाने की आवश्यकता होगी (कहें, मुझे चिकनी 60 एफपीएस एनीमेशन चाहिए) और यह बस स्मृति की बर्बादी है।

3) एनीमेशन बनाएं और एनीमेशन खत्म होने के बाद REMOVE_ITEM प्रेषण करें। यह सबसे उचित तरीका है जिसके बारे में मैं सोच सकता हूं, लेकिन फिर भी जब मैं कार्रवाई करता हूं तो मैं स्टोर में चीजों को बदलना चाहता हूं। उदाहरण के लिए, एनीमेशन कुछ सेकंड से अधिक समय ले सकता है और REMOVE_ITEM बैकएंड के साथ सिंक हो सकता है - बैकएंड एपीआई कॉल करने के लिए एनीमेशन खत्म करने का कोई कारण नहीं है।

पढ़ने के लिए धन्यवाद - कोई सुझाव?

+0

एनीमेशन जिसका कोई डेटा प्रभाव नहीं है, वह रेडक्स स्टोर के बाहर होना चाहिए। –

+0

@MaciejSikora हाँ, पूरी तरह से यहां सहमत हैं - इस तरह मुझे लगता है कि यह होना चाहिए। लेकिन फिर भी मुझे नहीं पता कि इसे हासिल करने का अच्छा तरीका क्या है। :( – shlajin

उत्तर

4

प्रतिक्रिया ReactCSSTransitionGroup सहायक वर्ग में इस समस्या का एक बड़ा समाधान है (https://facebook.github.io/react/docs/animation.html देखें)। इस विकल्प के साथ, पिछली रेंडर पर बच्चे के लिए डोम राज्य को रखकर, प्रतिक्रिया आपके लिए इसका ख्याल रखती है। आप बस अपने आइटम को ReactCSSTransitionGroup ऑब्जेक्ट में लपेटें।यह अपने बच्चों का ट्रैक रखता है, और जब इसे बच्चे के बिना प्रतिपादित किया जाता है, बच्चे के बिना प्रतिपादन करने के बजाय, यह बच्चे के साथ प्रस्तुत करता है, लेकिन बच्चे को एक सीएसएस कक्षा जोड़ता है (जिसे आप सीएसएस एनीमेशन ट्रिगर करने के लिए उपयोग कर सकते हैं, या आप सादगी के लिए सीएसएस संक्रमण का उपयोग कर सकते हैं)। फिर, एक टाइमआउट के बाद (ReactCSSTransitionGroup को पास किए गए प्रोप के रूप में कॉन्फ़िगर किया गया), बच्चे को डीओएम से हटा दिए जाने के साथ फिर से प्रस्तुत किया जाएगा।

ReactCSSTransitionGroup का उपयोग करने के लिए, आपको प्रतिक्रिया-एडॉन्स-सीएसएस-संक्रमण-समूह स्थापित करने के लिए npm की आवश्यकता होगी, और फिर 'प्रतिक्रिया-एडॉन्स-सीएसएस-संक्रमण-समूह' की आवश्यकता/आयात करें। एनीमेशन दस्तावेज़ अधिक विस्तृत जानकारी देते हैं।

याद रखने की एक बात - सुनिश्चित करें कि बच्चों के अद्वितीय, अपरिवर्तनीय कुंजी हैं। इंडेक्स का उपयोग करके कुंजी कुंजी गलत तरीके से व्यवहार करेगी।

+0

ग्रेट के साथ जाऊंगा, जो कि मैं ढूंढ रहा हूं उसके करीब है। जल्द ही कोशिश करेंगे, बहुत धन्यवाद! – shlajin

+0

धन्यवाद, बिल्कुल मुझे क्या चाहिए! देर से उत्तर के लिए खेद है हालांकि: पी – shlajin

2

तत्काल कार्य रेडक्स में समस्याग्रस्त हैं जो राज्य को बचाता है, इसलिए यदि हम कार्रवाई भेजते हैं और यह स्टोर बदल जाएगा तो स्टोर में यह परिवर्तन अगले राज्यों में उपलब्ध होगा, इसलिए हमारे पास ऐसी स्थिति हो सकती है जहां एनीमेशन प्रदर्शित हो रहा है क्योंकि स्टोर में ऐसा पैरामीटर सेट किया गया था।

घटक में
{ 
    type:"SOME_ANIMATION", 
    id: new Date().getTime() //we get timestamp of animation init 
} 

अगला जो चलाता है एनिमेशन पिछले एनीमेशन आईडी बचाने के लिए और अगर इसके मैच एनीमेशन नहीं करते:

redux तत्काल कार्रवाई के लिए मेरे समाधान (कार्रवाई उदाहरण कोड) जैसे कुछ आईडी जोड़ना है। मैं तो उदाहरण के लिए (घटक कोड) घटक राज्य का उपयोग करें:

componentDidUpdate(){ 

if (this.lastAnimationId===this.props.animation.id) 
return; //the same animation id so do not do anything 

//here setState or do animation because it is new one 

this.lastAnimationId=this.props.animation.id; //here set new id of last abnimation 

} 

धन्यवाद आईडी हम कार्रवाई से है जो राज्य पीछे कर रहे हैं के बिना केवल एक ही कार्रवाई हो सकती है। टाइमआउट के बाद क्रियाओं को उलट करने से समस्याएं पैदा हो सकती हैं क्योंकि यदि अन्य क्रिया (जो घटक से जुड़ी है) को रिवर्स एक्शन से पहले भेजा जाएगा तो एनीमेशन फिर से शुरू हो सकता है।

मेरे द्वारा प्रस्तावित प्रस्तावों का माइनस यह है कि एनीमेशन डेटा राज्य में मौजूद है, लेकिन यह एनीमेशन आईडी भी मौजूद है जो हमें इसके बारे में जानकारी देता है। तो हम कह सकते हैं कि स्टोर अंतिम प्रेषित एनीमेशन बचाता है।

+0

समाधान के लिए धन्यवाद। और प्रेषण 'ANIMATION_FINISHED' कार्रवाई के लिए कौन जिम्मेदार है? एनीमेशन स्वयं? – shlajin

+0

इस समाधान में आपको ऐसी कोई कार्रवाई की आवश्यकता नहीं है। मैंने इसे विपरीत कार्यों के बारे में पाठ में वर्णित किया है। यह आईडी के साथ त्वरित कार्रवाई है, तो यह राज्य में रहता है। –

+0

ओह, मैं देखता हूं कि अब आपका क्या मतलब है। दुर्भाग्य से, मैं अभी भी स्पष्ट रूप से यह नहीं बता सकता कि यह एक हटाने की कार्रवाई में कैसे मदद कर सकता है। अपने समाधान का उपयोग करके मुझे आइटम को "हटाया गया" के रूप में चिह्नित करना होगा + उन्हें एनीमेशन जोड़ना आईडी। हालांकि यह काम कर सकता है, यह अभी भी बहुत अच्छा नहीं है क्योंकि मैंने स्टोर में आइटम हटा दिए होंगे :( – shlajin

संबंधित मुद्दे