MapDispatchToProps क्या है?


358

मैं Redux लाइब्रेरी के लिए प्रलेखन पढ़ रहा था और इसका यह उदाहरण है:

राज्य को पढ़ने के अलावा, कंटेनर घटक कार्यों को भेज सकते हैं। इसी तरह से, आप एक फ़ंक्शन को परिभाषित कर सकते हैं जिसे कहा जाता है mapDispatchToProps()कि यह dispatch()विधि प्राप्त करता है और कॉलबैक प्रॉप्स लौटाता है जिसे आप प्रस्तुति घटक में इंजेक्ट करना चाहते हैं।

यह वास्तव में कोई मतलब नहीं है। mapDispatchToPropsजब आपके पास पहले से ही है तो आपको इसकी आवश्यकता क्यों है mapStateToProps?

वे यह आसान कोड नमूना भी प्रदान करते हैं:

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

क्या कोई कृपया आम आदमी की शर्तों में बता सकता है कि यह कार्य क्या है और यह क्यों उपयोगी है?

जवाबों:


577

मुझे लगता है कि जवाब में से कोई भी क्रिस्टलीकृत नहीं mapDispatchToPropsहै कि उपयोगी क्यों है।

यह वास्तव में केवल container-componentपैटर्न के संदर्भ में उत्तर दिया जा सकता है , जो मुझे पहले पढ़ने से सबसे अच्छी तरह से समझ में आया: कंटेनर घटक फिर उपयोग के साथ प्रतिक्रिया

संक्षेप में, आपका componentsकेवल सामान प्रदर्शित करने से संबंधित होना चाहिए। वे जिस स्थान से जानकारी प्राप्त करने वाले हैं, वही उनकी सहारा है

"प्रदर्शन सामग्री" (घटकों) से अलग है:

  • आपको प्रदर्शन करने के लिए सामान कैसे मिलेगा,
  • और आप घटनाओं को कैसे संभालते हैं।

जो है उसी के लिए containersहैं

इसलिए, componentपैटर्न में एक "अच्छी तरह से डिज़ाइन किया गया" इस तरह दिखता है:

class FancyAlerter extends Component {
    sendAlert = () => {
        this.props.sendTheAlert()
    }

    render() {
        <div>
          <h1>Today's Fancy Alert is {this.props.fancyInfo}</h1>
          <Button onClick={sendAlert}/>
        </div>
     }
}

देखें कि इस घटक को प्रॉपर से प्रदर्शित होने वाली जानकारी कैसे मिलती है (जो कि रिड्यूक्स स्टोर से होकर आई है mapStateToProps) और इसके प्रॉपर से इसका एक्शन फ़ंक्शन भी प्राप्त होता है sendTheAlert():।

इसी mapDispatchToPropsमें आता है: इसी मेंcontainer

// FancyButtonContainer.js

function mapDispatchToProps(dispatch) {
    return({
        sendTheAlert: () => {dispatch(ALERT_ACTION)}
    })
}

function mapStateToProps(state) {
    return({fancyInfo: "Fancy this:" + state.currentFunnyString})
}

export const FancyButtonContainer = connect(
    mapStateToProps, mapDispatchToProps)(
    FancyAlerter
)

मुझे आश्चर्य है कि अगर आप देख सकते हैं, अब यह container 1 है जो कि redux और डिस्पैच और स्टोर और स्टेट और ... सामान के बारे में जानता है।

componentपैटर्न में, FancyAlerter, प्रतिपादन कि सामान में से किसी के बारे में पता करने की जरूरत है जो करता है नहीं करता है: यह कम से कॉल करने के लिए अपने विधि हो जाता है onClick, बटन के अपने रंगमंच की सामग्री के माध्यम से।

और ... mapDispatchToPropsउपयोगी साधन था कि Redux कंटेनर को आसानी से उस फ़ंक्शन को उसके प्रॉप्स पर लिपटे घटक में पास करने देता है।

सभी बहुत डॉक्स में कार्य करने के उदाहरण की तरह इस दिखता है, और एक अन्य जवाब यहाँ है, लेकिन मैं पैटर्न के आलोक में यह कास्ट करने के लिए जोर देना कोशिश की है क्यों

(ध्यान दें: आप mapStateToPropsउसी उद्देश्य के लिए उपयोग नहीं कर सकते हैं mapDispatchToPropsजिस मूल कारण के लिए आपके dispatchअंदर पहुंच नहीं है mapStateToProp। इसलिए आप mapStateToPropsलिपटे घटक को उपयोग करने वाली विधि देने के लिए उपयोग नहीं कर सकते dispatch

मुझे नहीं पता कि उन्होंने इसे दो मानचित्रण कार्यों में तोड़ने के लिए क्यों चुना - यह mapToProps(state, dispatch, props) दोनों करने के लिए IE एक कार्य करने के लिए निश्चित हो सकता है !


1 ध्यान दें कि मैंने जानबूझकर कंटेनर का नाम दिया था FancyButtonContainer, यह उजागर करने के लिए कि यह एक "चीज़" है - कंटेनर की "चीज़" के रूप में पहचान (और इसलिए अस्तित्व!) कभी-कभी शॉर्टहैंड में खो जाती है।

export default connect(...) ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

वाक्यविन्यास जो ज्यादातर उदाहरणों में दिखाया गया है


5
मैं अब भी जानना चाहूंगा: स्टोर से सीधे कॉल करके स्टोर की गई कार्यक्षमता के बारे में क्या आवश्यक कार्यक्षमता को नियंत्रित नहीं किया जा सकता है?
पिक्सेलपैक्स

8
@ user2130130 कोई नहीं। यह अच्छे डिजाइन के बारे में है। यदि आपने अपने घटक को store.dispatch पर युग्मित किया है, तो जब आप फ़ैक्स को फिर से करने का निर्णय लेते हैं, या इसे कुछ ऐसी जगह पर उपयोग करना चाहते हैं, जो redxu आधारित नहीं है (या कोई अन्य चीज़ जो मैं अभी नहीं सोच सकता हूं) आप एक के साथ फंस गए हैं बहुत सारे बदलाव। आपका प्रश्न "हमें अच्छे डिज़ाइन प्रथाओं के साथ परेशान क्यों करता है" के लिए सामान्यीकरण करता है - आपको समान कार्यक्षमता मिलती है, हालांकि आप इसे कोड करते हैं। MapDispatchToProps प्रदान किया जाता है ताकि आप अच्छी तरह से डिज़ाइन किए गए, साफ-सुथरे घटकों को लिख सकें।
ग्रीनएजजादे

4
जो मुझे वास्तव में यहाँ नहीं मिलता है, वह यह है: क्या वह ALERT_ACTIONक्रिया क्रिया है या typeवह क्रिया फलन से लौटी है? : / तो चकित
जेमी हटबर

1
@JamieHutber सख्ती से, ALERT_ACTION का इस सवाल से कोई लेना-देना नहीं है। यह प्रेषण करने के लिए एक वैध तर्क है, और जैसा कि होता है, मेरे कोड में यह "एक्शन बिल्डर" से आता है, जो एक ऐसी वस्तु लौटाता है जो डिस्पैच का उपयोग करती है, जैसा कि redux.js.org/docs/api/Store.html#dadatch के रूप में वर्णित है । यहां मुख्य बिंदु यह है कि प्रेषण कॉल कैसे करें कंटेनर में वर्णित किया गया है और घटक प्रॉपर पर पारित किया गया है। घटक केवल अपने रंगमंच की सामग्री, कहीं और से कार्य करता है। इस पैटर्न में इसे करने का "गलत" तरीका घटक को प्रेषण देना और घटक में समान कॉल करना होगा।
ग्रीनएजेड जेड

1
आप एक से अधिक कार्रवाई रचनाकारों रंगमंच की सामग्री के रूप में बच्चे के घटक को पास करने की जरूरत है, तो एक विकल्प उन्हें mapDispatchToProps अंदर bindActionCreators (देखें के साथ रैप करने के लिए है redux.js.org/docs/api/bindActionCreators.html ); एक अन्य विकल्प बस कनेक्ट करने के लिए एक्शन क्रिएटर्स की एक वस्तु प्रदान करना है (), उदाहरण के लिए, कनेक्ट करें (mapStateToProps, {actioncreators}), प्रतिक्रिया-रिड्यूक उन्हें आपके लिए प्रेषण () के साथ लपेट देगा।
डेव

81

यह मूल रूप से एक आशुलिपि है। इसलिए लिखने के बजाय:

this.props.dispatch(toggleTodo(id));

आप अपने उदाहरण कोड में दिखाए गए अनुसार MapDispatchToProps का उपयोग करेंगे, और फिर कहीं और लिखें:

this.props.onTodoClick(id);

या इस मामले में अधिक संभावना है, आपके पास इवेंट हैंडलर के रूप में होगा:

<MyComponent onClick={this.props.onTodoClick} />

इस पर डैन अब्रामोव द्वारा एक उपयोगी वीडियो यहां है: https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-voublegodolist


धन्यवाद। मैं भी सोच रहा हूँ, प्रेषण पहली जगह में प्रॉप्स में कैसे जोड़ा जाता है?
कोड व्हिसपर

14
यदि आप अपना स्वयं का mapDispatchफ़ंक्शन प्रदान नहीं करते हैं , तो Redux एक डिफ़ॉल्ट का उपयोग करेगा। वह डिफ़ॉल्ट mapDispatchफ़ंक्शन केवल dispatchफ़ंक्शन संदर्भ लेता है , और आपको इसे देता है this.props.dispatch
मार्करसन

7
प्रेषण विधि प्रदाता घटक
डिएगो हज

55

mapStateToProps()एक उपयोगिता है जो आपके घटक को अद्यतन स्थिति प्राप्त करने में मदद करती है (जो कुछ अन्य घटकों द्वारा अद्यतन की जाती है),
mapDispatchToProps()एक उपयोगिता है जो आपके घटक को एक एक्शन इवेंट (डिस्पैचिंग एक्शन जो एप्लिकेशन स्टेट के परिवर्तन का कारण हो सकता है) को आग लगाने में मदद करेगी।


23

mapStateToProps, mapDispatchToPropsऔर connectसे react-reduxपुस्तकालय अपने तक पहुँचने के लिए एक सुविधाजनक तरीका प्रदान करता है stateऔर dispatchअपने स्टोर के कार्य करते हैं। तो मूल रूप से कनेक्ट एक उच्च आदेश घटक है, आप एक आवरण के रूप में भी सोच सकते हैं यदि यह आपके लिए समझ में आता है। इसलिए हर बार आपके stateबदले mapStateToPropsजाने के stateबाद आपको अपने नए के साथ बुलाया जाएगा और बाद में जैसे ही आप propsअपडेट करेंगे घटक ब्राउज़र में आपके घटक को प्रस्तुत करने के लिए रेंडर फ़ंक्शन चलाएगा। आपके घटक mapDispatchToPropsपर कुंजी-मान भी संग्रहीत propsकरता है, आमतौर पर वे एक फ़ंक्शन का रूप लेते हैं। इस तरह से आप stateअपने घटक onClick, onChangeघटनाओं से परिवर्तन को ट्रिगर कर सकते हैं।

डॉक्स से:

const TodoListComponent = ({ todos, onTodoClick }) => (
  <ul>
    {todos.map(todo =>
      <Todo
        key={todo.id}
        {...todo}
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>
)

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

function toggleTodo(index) {
  return { type: TOGGLE_TODO, index }
}

const TodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList) 

यह भी सुनिश्चित करें कि आप रिएक्ट स्टेटलेस फ़ंक्शंस और हायर-ऑर्डर कंपोनेंट्स से परिचित हैं


तो प्रेषण मूल रूप से घटना की तरह है?
संहिता व्हिस्पर

2
यह घटना से संबंधित हो सकता है, प्रेषण केवल एक फ़ंक्शन है और आपके एप्लिकेशन स्थिति को बदलने का एकमात्र तरीका है । mapStateToProps एक तरह से बेनकाब करने के लिए है प्रेषण अपने के समारोह दुकान घटक प्रतिक्रिया करने के लिए। यह भी ध्यान दें कि कनेक्ट वास्तव में रिडक्स का हिस्सा नहीं है, यह सिर्फ एक उपयोगिता है और बॉयलरप्लेट लाइब्रेरी को कम करता है जिसे रिएक्ट-रिक्स के साथ काम करने के लिए प्रतिक्रिया और रिडक्स कहा जाता है । यदि आप अपने स्टोर को रूट रिएक्शन कंपोनेंट से बच्चों को पास करते हैं, तो आप बिना प्रतिक्रिया-रिड्यूस के ही परिणाम प्राप्त कर सकते हैं ।
व्लादि फिलिमन

3

mapStateToPropsप्राप्त करता है stateऔर propsघटक को पास करने के लिए आपको राज्य से सहारा निकालने की अनुमति देता है।

mapDispatchToPropsप्राप्त करता है dispatchऔर propsआपके लिए एक्शन क्रिएटर्स को बाँधने के लिए होता है ताकि जब आप परिणामी फंक्शन को अंजाम दें तो एक्शन डिस्पैच हो जाए।

मुझे लगता है कि यह केवल dispatch(actionCreator())आपके घटक के भीतर होने से बचाता है और इस प्रकार इसे पढ़ना थोड़ा आसान है।

https://github.com/reactjs/react-redux/blob/master/docs/api.md#arguments


धन्यवाद, लेकिन dispatchविधि का मूल्य क्या है ? यह कहां से आता है?
कोड व्हिसपर

ओह। मूल रूप से डिस्पैच करने से एक्शन की शुरुआत रिडक्स / फ्लक्स यूनिडायरेक्शनल फ्लो से होती है। लगता है कि अन्य उत्तर आपके प्रश्न का उत्तर इससे बेहतर देते हैं।
हैरी मोरेनो

इसके अलावा, प्रेषण विधि <Provider/>स्वयं द्वारा प्रदान की गई वृद्धि से आती है। यह इस बात की गारंटी देने के लिए कि वह अपने बच्चों के घटकों में प्रेषण उपलब्ध है, अपना उच्च क्रम घटक जादू करता है।
रिकार्डो मैगलाशेस

3

अब मान लीजिए कि रिडक्स के लिए एक क्रिया है:

export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

जब आप इसे आयात करते हैं,

import {addTodo} from './actions';

class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.onTodoClick(); // This prop acts as key to callback prop for mapDispatchToProps
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

const mapDispatchToProps = dispatch => {
    return {
      onTodoClick: () => { // handles onTodoClick prop's call here
        dispatch(addTodo())
      }
    }
}

export default connect(
    null,
    mapDispatchToProps
)(Greeting);

जैसा कि फ़ंक्शन नाम कहता है mapDispatchToProps(), नक्शा dispatchकार्रवाई (हमारे घटक के रंगमंच की सामग्री)

तो प्रोप कार्य onTodoClickकरने के लिए एक कुंजी है mapDispatchToPropsजो कार्यवाही को भेजने के लिए दूर-दूर को दर्शाता है addTodo

इसके अलावा यदि आप कोड को ट्रिम करना चाहते हैं और मैनुअल कार्यान्वयन को बायपास करना चाहते हैं, तो आप यह कर सकते हैं,

import {addTodo} from './actions';
class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.addTodo();
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

export default connect(
    null,
    {addTodo}
)(Greeting);

जिसका बिल्कुल मतलब है

const mapDispatchToProps = dispatch => {
    return {
      addTodo: () => { 
        dispatch(addTodo())
      }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.