Redux में अपडेट होने के बाद कॉलबैक को कैसे ट्रिगर करें?


86

प्रतिक्रिया में, राज्य को तुरंत अपडेट नहीं किया जाता है, इसलिए हम कॉलबैक का उपयोग कर सकते हैं setState(state, callback)। लेकिन यह Redux में कैसे करें?

कॉल करने के बाद this.props.dispatch(updateState(key, value)), मुझे तुरंत अद्यतन स्थिति के साथ कुछ करने की आवश्यकता है।

क्या कोई तरीका है जिससे मैं नवीनतम स्थिति के साथ कॉलबैक कर सकता हूं जैसे कि मैं रिएक्ट में क्या करता हूं?


क्या आप उपयोग करते हैं thunk?
प्राणेश रवि

1
मुझे लगता dispatch()है कि एक तुल्यकालिक गतिविधि है। अद्यतन स्थिति अगली पंक्ति में उपलब्ध होनी चाहिए।
प्राणेश रवि

3
@PraneshRavi मैंने ऐसा सोचा। लेकिन मुझे पुराना राज्य मिल गया। मैंने उपयोग नहीं किया thunk
ब्रिक यांग


1
हां प्रेषण तुल्यकालिक है, लेकिन घटक के रंगमंच की सामग्री के बाद का अद्यतन नहीं है। इसलिए अगली पंक्ति में रिडक्स स्थिति को अद्यतन किया जाता है, लेकिन घटक का रंग अभी तक नहीं है।
आमिक

जवाबों:


112

नए प्रॉप्स प्राप्त करने के लिए घटक को अपडेट किया जाना चाहिए।

अपने लक्ष्य को प्राप्त करने के तरीके हैं:

1. ComponentsDidUpdate चेक करें यदि मान बदल गया है, तो कुछ करें ..

 componentDidUpdate(prevProps){
     if(prevProps.value !== this.props.value){ alert(prevProps.value) }
  }

2. रिडक्स-वादा (मिडलवेयर वादे के हल किए गए मूल्य को भेजेगा)

export const updateState = (key, value)=>
Promise.resolve({
  type:'UPDATE_STATE',
  key, value
})

फिर घटक में

this.props.dispatch(updateState(key, value)).then(()=>{
   alert(this.props.value)
})

2. रिडक्स-थंक

export const updateState = (key, value) => dispatch => {
  dispatch({
    type: 'UPDATE_STATE',
    key,
    value,
  });
  return Promise.resolve();
};

फिर घटक में

this.props.dispatch(updateState(key, value)).then(()=>{
   alert(this.props.value)
})

6
अपने redux-thunkउदाहरण में, आप का उपयोग करें dispatchजैसे कि यह तुल्यकालिक है। क्या यह मामला है?
डैनी हार्डिंग

2
@ डैनीहिरिंग dispatchसमकालिक नहीं है। बिना Promise.resolve(), this.props.valueअभी भी पुराने मूल्य को वापस करेगा। कुछ प्रकार के एसिंक्स डिफरल की अभी भी जरूरत है ( setTimeoutउदाहरण के लिए भी काम करना होगा)।
द्राजेन बोजेलोवुक

4
@DrazenBjelovuk मुझे आश्चर्य हो रहा है क्योंकि redux-thunk उदाहरण में updateState फ़ंक्शन ने प्रेषण (someAction) को तुरंत लौटा दिया है उसके बाद Promise.resolve ()। वादा तुरंत हल हो जाता है, जो मुझे लगता है कि रिड्यूस स्टोर अपडेट और घटक में कहा गया है के बीच एक दौड़ की स्थिति पैदा करेगा। क्योंकि प्रेषण एक वादा वापस नहीं करता है या एक कॉलबैक स्वीकार नहीं करता है, मुझे नहीं लगता कि यह जानने का एक सटीक तरीका है कि रिड्यूक्स स्टोर को कब अपडेट किया गया है। मुझे लगता है कि इस मामले में जस्ट-बोरिस का जवाब सही है
डैनी हार्डिंग

2
@DannyHiring हाँ मैं सहमत हूँ कि यह विधि निश्चित रूप से आग की गारंटी नहीं है, बस यह दर्शाते हुए कि प्रेषण समकालिक नहीं है।
द्राज़न बेज़ेलोवुक

1
मैं यहाँ redux-thunk समाधान का उपयोग करने की कोशिश कर रहा हूँ, लेकिन मैं केवल प्राप्त करता हूं TypeError: _this.props.dispatch is not a function?
क्रिल्को

14

रिएक्ट के बारे में सबसे महत्वपूर्ण बिंदु एक तरफ़ा डेटा प्रवाह है। आपके उदाहरण में इसका मतलब है, कि एक प्रेषण और राज्य परिवर्तन से निपटने को रोकना चाहिए।

आपको यह नहीं सोचना चाहिए कि "मैंने किया A, अब Xबन गया है Yऔर मैं इसे संभालता हूं", लेकिन "मैं क्या करता हूं जब Xबन जाता है Y", बिना किसी संबंध के A। स्टोर स्टेट को म्यूटेंट सोर्स से अपडेट किया जा सकता है, आपके कंपोनेंट के अलावा, टाइम ट्रैवल भी स्टेट को बदल सकता है और इसे आपके Aडिस्पैच प्वाइंट से नहीं गुजारा जाएगा ।

मूल रूप से इसका मतलब है कि आप का उपयोग करना चाहिए componentWillReceivePropsक्योंकि यह @Utro द्वारा प्रस्तावित किया गया था


यह वह उत्तर है जो वास्तव में खोज रहा है (हालाँकि ऐसा लग रहा है कि उसे इस बारे में जानकारी नहीं है ..)
refaelio

1
मैं मानता हूँ, लेकिन इस पर विचार किया जाना एक antipattern लगता है: hackernoon.com/...
गियाकोमो Cerquone

1
अब हम क्या करते हैं कि componentWillReceivePropsपदावनत किया जाता है? static getDerivedStateFromProps()एक उपयुक्त प्रतिस्थापन नहीं लगता क्योंकि यह कॉलबैक नहीं कह सकता, जहाँ तक मैं बता सकता हूँ
M3RS

7

हुक एपीआई के साथ:

useEffect इनपुट के रूप में प्रोप के साथ।

import React, { useEffect} from 'react'
import { useSelector } from 'react-redux'

export default function ValueComponent() {
   const value = useSelectror(store => store.pathTo.value)

   useEffect(() => {
     console.log('New value', value) 
     return () => {
        console.log('Prev value', value) 
     }

   }, [value])

   return <div> {value} </div>
}

स्वीकृत उत्तर रिएक्ट हुक से पहले लिखा गया था। हुक की शुरुआत के बाद अब यह स्वीकृत उत्तर होना चाहिए। परिवर्तनों को संभालने के लिए यह अधिक प्रतिक्रियाशील तरीका है।
tif

5

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

http://redux.js.org/docs/api/Store.html#subscribelistener


2
subscribeकेवल आग जब एक कार्रवाई भेजा जाता है। ऐसा कोई तरीका subscribeनहीं है जिससे आपको पता चल सके कि आपकी API कॉल ने कोई डेटा वापस किया है .. मुझे लगता है! : डी
मिहिर

आपका अनुरोध पूरा होने पर (सफलतापूर्वक या असफल रूप से) आप दूसरी कार्रवाई भेज सकते हैं।
जाम

मुझे विश्वास नहीं हो रहा है कि यहां प्रस्तावित अन्य समाधानों में से कोई भी वास्तव में काम करता है, क्योंकि मुझे राज्य के अद्यतन होने के बाद हल करने के लिए एक वादा या कॉलबैक के लिए कोई रास्ता नहीं दिखता है। इस पद्धति को हर स्टोर अपडेट के लिए बुलाया जाता है, न कि केवल एक जो आपके ईवेंट के बाद होता है, लेकिन इसके आसपास काम करने के लिए बहुत कठिन नहीं होना चाहिए। विशेष रूप से, लिंक आपके द्वारा लिंक किए गए पृष्ठ से एक कस्टम अवलोकनीय उपयोगिता लिखता है जो बहुत उपयोगी है।
नेट कुह्न

लिंक पेज नहीं मिला
भरत मोदी

2

आप कॉलबैक के साथ एक थंक का उपयोग कर सकते हैं

myThunk = cb => dispatch =>
  myAsyncOp(...)
    .then(res => dispatch(res))
    .then(() => cb()) // Do whatever you want here.
    .catch(err => handleError(err))

मैं क्या जरूरत थी के लिए बिल्कुल सही!
JSON C11

-1

एक सरल समाधान के रूप में आप उपयोग कर सकते हैं: redux-वादा

लेकिन अगर आप redux-thunk का उपयोग कर रहे हैं , तो आपको इस तरह से करना चाहिए:

function addCost(data) {
  return dispatch => {
    var promise1 = new Promise(function(resolve, reject) {
      dispatch(something);
     });
    return promise1;
  }
}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.