2016-04-21 20 views
5

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

// DESTINATIONS 
// ============================================== 

export const DESTINATION_REQUEST = 'DESTINATION_REQUEST'; 
export const DESTINATION_SUCCESS = 'DESTINATION_SUCCESS'; 
export const DESTINATION_FAILURE = 'DESTINATION_FAILURE'; 

export function loadDestination (params, query) { 

    const state = params.state ? `/${params.state}` : ''; 
    const region = params.region ? `/${params.region}` : ''; 
    const area = params.area ? `/${params.area}` : ''; 

    return (dispatch) => { 
     return api('location', {url: `/accommodation${state}${region}${area}`}).then((response) => { 
      const destination = formatDestinationData(response); 

      dispatch({ 
       type: DESTINATION_SUCCESS, 
       destination 
      }); 
     }); 
    }; 
} 





// PROPERTIES 
// ============================================== 

export const PROPERTIES_REQUEST = 'PROPERTIES_REQUEST'; 
export const PROPERTIES_SUCCESS = 'PROPERTIES_SUCCESS'; 
export const PROPERTIES_FAILURE = 'PROPERTIES_FAILURE'; 

export function loadProperties (params, query, rows = 24) { 

    return (dispatch, getState) => { 

     console.log(getState()); 

     return api('search', {locationId: xxxxxx, rows: rows}).then((response) => { 
      const properties = response.results.map(formatPropertiesData); 

      dispatch({ 
       type: PROPERTIES_SUCCESS, 
       properties 
      }); 
     }); 
    }; 
} 

इन उनके रिश्तेदार reducers के साथ संयुक्त कर रहे हैं:

मैं एक दो कार्यवाही

// DESTINATIONS REDUCERS 
// ============================================== 

export default function destination (state = [], action) { 
    switch (action.type) { 
    case DESTINATION_SUCCESS: 
     return action.destination; 
    default: 
     return state; 
    } 
} 





// PROPERTIES REDUCERS 
// ============================================== 

export default function properties (state = [], action) { 
    switch (action.type) { 
    case PROPERTIES_SUCCESS: 
     return action.properties; 
    default: 
     return state; 
    } 
} 

और वे एक घटक के भीतर से कहा जाता है (connectDataFetchers बुलाया कार्यों के माध्यम से लूप और उन्हें रिटर्न सर्वर साइड प्रतिपादन के लिए घटक के लिए):

// PROPTYPES 
 
// ============================================== 
 

 
Search.propTypes = { 
 
    destination: PropTypes.object.isRequired, 
 
    properties: PropTypes.array.isRequired 
 
}; 
 

 

 

 

 

 
// ACTIONS 
 
// ============================================== 
 

 
function mapStateToProps ({destination, properties}) { 
 
    return {destination, properties}; 
 
} 
 

 

 

 

 

 
// CONNECT & EXPORT 
 
// ============================================== 
 

 
export default connect(mapStateToProps)(
 
    connectDataFetchers(Search, [loadDestination, loadProperties]) 
 
);

export default function connectDataFetchers (Component, actionCreators) { 
 
    return class DataFetchersWrapper extends React.Component { 
 
     static propTypes = { 
 
      dispatch: React.PropTypes.func.isRequired, 
 
      location: React.PropTypes.object.isRequired, 
 
      params: React.PropTypes.object.isRequired 
 
     }; 
 
     
 
     static fetchData (dispatch, params = {}, query = {}) { 
 
      return Promise.all(
 
       actionCreators.map((actionCreator) => dispatch(actionCreator(params, query))) 
 
      ); 
 
     } 
 

 
     componentDidMount() { 
 
      DataFetchersWrapper.fetchData(
 
       this.props.dispatch, 
 
       this.props.params, 
 
       this.props.location.query 
 
      ); 
 
     } 
 

 
     render() { 
 
      return (
 
       <Component {...this.props} /> 
 
      ); 
 
     } 
 
    }; 
 
}

मैं पहली बार कार्रवाई (loadDestination) जो वापस आ जाएगी एक आईडी तो फिर दूसरी कार्रवाई करने के लिए पारित करने के लिए उस स्थान आईडी के साथ गुण लोड करने के लिए की जरूरत है चलाने के लिए की जरूरत है।

अगर मैं एक locationID हार्डकोड इस ठीक काम करता है, लेकिन अगर मैं getState() के माध्यम से loadProperties में राज्य तक पहुँचने का प्रयास तो यह { destination: [], properties: [] } देता है।

क्या राज्य के माध्यम से पहली कार्रवाई से मूल्य तक पहुंचने का कोई तरीका है?

समाधान

इस किसी नए कार्य है कि आदेश मैं जरूरत में दो अन्य कार्यों डिस्पैच बनाया pierrepinard_2

@ से सुझाव निम्न काम करने के लिए प्राप्त करने के लिए प्रबंधित:

// SEARCH 
 
// ============================================== 
 

 
export function loadSearch (params, query) { 
 
    
 
    return (dispatch) => { 
 
     return dispatch(
 
      loadDestination(params, query) 
 
     ).then(() => { 
 
      return dispatch(
 
       loadProperties(params, query) 
 
      ) 
 
     }) 
 
    } 
 
} 
 

 
// DESTINATIONS 
 
// ============================================== 
 

 
export const DESTINATION_REQUEST = 'DESTINATION_REQUEST'; 
 
export const DESTINATION_SUCCESS = 'DESTINATION_SUCCESS'; 
 
export const DESTINATION_FAILURE = 'DESTINATION_FAILURE'; 
 

 
export function loadDestination (params, query) { 
 

 
    const state = params.state ? `/${params.state}` : ''; 
 
    const region = params.region ? `/${params.region}` : ''; 
 
    const area = params.area ? `/${params.area}` : ''; 
 

 
    return (dispatch) => { 
 
     return api('location', {url: `/accommodation${state}${region}${area}`}).then((response) => { 
 
      const destination = formatDestinationData(response); 
 
      
 
      dispatch({ 
 
       type: DESTINATION_SUCCESS, 
 
       destination 
 
      }); 
 
     }); 
 
    }; 
 
} 
 
    
 
    // PROPERTIES 
 
// ============================================== 
 

 
export const PROPERTIES_REQUEST = 'PROPERTIES_REQUEST'; 
 
export const PROPERTIES_SUCCESS = 'PROPERTIES_SUCCESS'; 
 
export const PROPERTIES_FAILURE = 'PROPERTIES_FAILURE'; 
 

 
export function loadProperties (params, query, rows = 24) { 
 

 
    return (dispatch, getState) => { 
 
     return api('search', {locationId: getState().destination.id, rows: rows}).then((response) => { 
 
      const properties = response.results.map(formatPropertiesData); 
 

 
      dispatch({ 
 
       type: PROPERTIES_SUCCESS, 
 
       properties 
 
      }); 
 
     }); 
 
    }; 
 
}

तब घटक में मैं केवल एक क्रिया का अनुरोध करता हूं:

export default connect(mapStateToProps)(
 
    connectDataFetchers(Search, [loadSearch]) 
 
);

+0

काम करता है आप कैसे कॉल loadDestination और loadProperties साझा किया जा सका है? –

+0

@DamienLeroux - क्या मैं खोज घटक प्लस 'connectDataFetchers' समारोह – Paul

उत्तर

3

आप Promise.all() अपने fetchData() विधि में उपयोग करें: अपने कार्यों, समानांतर में भेज दिया जाता है एक के बाद एक नहीं।

यह सुनिश्चित करने के लिए कि आप पहले गंतव्य को कॉल करते हैं, फिर गुणों के लिए, आपको अपने खोज घटक के लिए एक विशिष्ट एसिंक एक्शन निर्माता बनाना चाहिए। यह async एक्शन निर्माता इस मामले में आपको आवश्यक अनुरोधों को लागू करेगा।

+0

मैंने कोशिश की है कि शुरू में एक अलग समारोह के भीतर दो कार्यों बुला लेकिन वह mapStateToProps में संबंधित चर के अटैच नहीं किया से कुछ और कोड जोड़ दिया है। मैं उस रिश्ते को कैसे बनाए रखूं? – Paul

+0

मुझे समझ में नहीं आता कि आपका क्या मतलब है। MapStateToProps() फ़ंक्शन आपके प्रोप को आपके ऐप की एकमात्र स्थिति से पुनर्प्राप्त करता है। क्या यह आदेश के साथ एक समस्या है जिसमें एपीआई अनुरोध प्राप्त होते हैं? यदि आप अपने async अनुरोधों को संभालने के लिए रेडक्स-थंक मिडलवेयर का उपयोग करते हैं और फिर() के साथ श्रृंखला प्रेषण() कॉल करना चाहते हैं, तो हमेशा अपने एसिंक एक्शन क्रिएटर में वादे वापस करना सुनिश्चित करें (https://github.com/gaearon में अधिक जानकारी/redux-thunk # रचना)। उदाहरण के लिए, आपको "प्रेषण (...) वापस करना चाहिए;" आपके एक्शन निर्माता में। –

+0

धन्यवाद @ pierrepinard_2 - रेडक्स-थंक सुझाव के बाद मुझे यह काम करने के लिए मिला और ऊपर दिए गए समाधान को जोड़ा है – Paul

0

मैं @ pierrepinard_2 से सहमत हूं।

ब्लूबर्ड से promise.map का उपयोग करके, आप सभी दिए गए वादे को सिंक्रनाइज़ तरीके से कॉल करने में सक्षम होना चाहिए।

यह post on stack overflow आपको उस मामले में मदद करनी चाहिए।

हमें बताएं कि क्या यह

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