2016-09-26 14 views
9

मैंने यह पता लगाने की कोशिश कर एक दीवार मारा है कि जेएसओएन डेटा जो मैं प्राप्त कर रहा हूं और राज्य पर भंडारण क्यों कर रहा हूं, मेरे घटक प्रोप में मैप नहीं किया जा रहा है, फिर भी फ़ंक्शन mapStateToProps() फ़ंक्शन के भीतर दिखाई देता है। क्या मैं कुछ गलत कर रहा हूं कि मैं यहां नहीं देख रहा हूं?मानचित्र के भीतर Redux ऐप घोंसले राज्य में mapStateToProps()?

संपादित करें: स्पष्ट रूप से राज्य पर संपत्तियों को घटक में मैप किया जा रहा है लेकिन घोंसला है। data संपत्ति, mapStateToProps() के भीतर से लॉग इन होने पर, state.state.data के माध्यम से एक्सेस किया जाना चाहिए। इससे पहले (reducer देखें), जब action.data लॉग है, तो डेटा अपेक्षित के रूप में दिखाई देता है। कोई अजीब घोंसला नहीं। शायद connect फ़ंक्शन के साथ कुछ गलत है?

देखें कि कैसे वहाँ एक राज्य संपत्ति राज्य वस्तु के भीतर बसा है:

class ViewSelector extends Component { 
    componentWillMount() { 
    this.props.fetchDataAsync('VIEW ALL'); 
    } 

    selectView(event) { 
    // this.props.data comes up undefined despite state being mapped 
    // to the component props 
    console.log('props: ' + this.props.data); 
    this.props.filterData(event.target.innerHTML, this.props.data); 
    } 

    render() { 
    return (
     <section> 
     <nav> 
      <button onClick={this.selectView.bind(this)}>VIEW ALL</button> 
      <button onClick={this.selectView.bind(this)}>VIEW LAST WEEK</button> 
      <button onClick={this.selectView.bind(this)}>VIEW LAST MONTH</button> 
     </nav> 
     <Dashboard data={this.props.data}/> 
     </section> 
    ); 
    } 
} 

function mapStateToProps(state) { 
    console.log(state); 
    // this console.log shows the state with the data property. 
    return { 
    data: state.data 
    }; 
} 

export default connect(mapStateToProps, actions)(ViewSelector); 

संपादित करें:

: यहाँ स्पष्टीकरण के लिए कम करने है

See the data property populated within the state object

नीचे मेरी घटक है

import { 
    FETCH_DATA, 
    FETCH_DATA_SUCCESS, 
    FETCH_DATA_FAILURE, 
    FILTER_DATA 
} from '../actions/types'; 
import { getLastWeek, getLastMonth } from './reducer_helper'; 

const initialState = { 
    error: '', 
    loading: false, 
    data: [] 
}; 

/* eslint-disable */ 
const app = (state = initialState, action) => { 
    switch(action.type) { 
    case FETCH_DATA: 
     return { ...state, error: '', loading: true }; 
    case FETCH_DATA_SUCCESS: 
     // console.log(action.data) returns data as expected. 
     // no nesting...until it hits the mapStateToProps() function 
     return { ...state, error: '', loading: false, data: action.data }; 
    case FETCH_DATA_FAILURE: 
     return { ...state, error: action.error, loading: false }; 
    case FILTER_DATA: 
     let data; 
     if (action.view === 'VIEW LAST WEEK') { 
     data = getLastWeek(state.data); 
     } else if (action.view === 'VIEW LAST MONTH') { 
     data = getLastMonth(state.data); 
     } else { 
     data = state.data; 
     } 
     return { ...state, error: '', loading: false, data }; 
    } 
    return state; 
} 

export default app; 

स्पष्टीकरण के लिए कार्य निर्माता

export function fetchData() { 
    return { 
    type: FETCH_DATA 
    }; 
} 

export function fetchDataSuccess(data) { 
    return { 
    type: FETCH_DATA_SUCCESS, 
    data: data 
    }; 
} 

export function fetchDataFailure(data) { 
    return { 
    type: FETCH_DATA_FAILURE, 
    data 
    }; 
} 

export function filterData(view) { 
    return { 
    type: FILTER_DATA, 
    view 
    }; 
} 

export function fetchDataAsync() { 
    return dispatch => { 
    dispatch(fetchData()); 

    axios.get(DATA_URL) 
    .then(res => { 
     dispatch(fetchDataSuccess(res.data)); 
    }).catch(err => { 
     dispatch(fetchDataFailure(err)); 
    }); 
    }; 
} 

कैसे पूरे एप्लिकेशन में प्रदान की जा रही है & Redux दुकान:

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 
import { createStore, applyMiddleware } from 'redux'; 
import thunk from 'redux-thunk'; 

import App from './components/app'; 
import reducers from './reducers'; 

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore); 

ReactDOM.render(
    <Provider store={createStoreWithMiddleware(reducers)}> 
    <App /> 
    </Provider> 
    , document.querySelector('.container')); 
+0

mapStateToProps को पूरी स्थिति को तर्क के रूप में प्राप्त करना माना जाता है, आप वास्तव में क्या पूछ रहे हैं? – StateLess

+0

जब मैं '{data: state.data} 'वापस लौटाता हूं तो डेटा सरणी मौजूद है। लेकिन जब मैं घटक के भीतर उस डेटा को 'this.props.data' के साथ एक्सेस करने का प्रयास करता हूं तो यह अपरिभाषित होता है। तो यह * लगता है * सड़क के साथ कहीं कहीं कुछ खो रहा है। या मैं पूरी तरह से गलत तरीके से गलत हूं कि 'mapStateToProps' क्या कर रहा है ... – Jose

+0

क्या आप – StateLess

उत्तर

7

ज्यादा की समीक्षा, डिबगिंग और पूछ अन्य devs के बाद, संक्षेप में इस समस्या मैं का सामना करना पड़ रहा था: शायद बेहतर एक initialState वस्तु के साथ शुरू करने के लिए कम करने और कैसे यह एक मुख्य "प्रकट में आयात किया जा रहा था "अन्य सभी reducers का प्रबंधन करने के लिए फ़ाइल।

असल में, क्योंकि मैं केवल इस परियोजना में एक रेड्यूसर का उपयोग कर रहा था, वहां एक मेनिफेस्ट रेड्यूसर फ़ाइल की आवश्यकता नहीं थी। नीचे देखें:

import { combineReducers } from 'redux'; 
import Reducer from './reducer'; 

const rootReducer = combineReducers({ 
    state: Reducer 
}); 

export default rootReducer; 

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

state = { 
    // here is one nested reducer with its own properties 
    data: { 
    type: // somevalue, 
    filtered: true 
    }, 
    // here is another 
    user: { 
    name: // somename, 
    password: // somepassword 
    } 
}; 

संक्षेप में ...इस बात पर ध्यान रखें कि आपके रेड्यूसर को आपके createStore फ़ंक्शन में कैसे आयात किया जा रहा है और यदि यह केवल रेड्यूसर का उपयोग किया जा रहा है या यदि मैनिफेस्ट फ़ाइल के माध्यम से कई रेड्यूसर चल रहे हैं।

चीयर्स।

+0

गठबंधन रेड्यूसर कुंजी के तहत उपयोग किए जाने वाले कुंजी के तहत प्रत्येक रेड्यूसर की स्थिति को घोंसला करता है (इसलिए राज्य के नीचे, रेड्यूसर के लिए, ऊपर दिए गए कोड में)। आपके मामले में, आपको combineReducers को कॉल नहीं करना चाहिए, क्योंकि आपके पास केवल एक reducer है। एक गैर-तुच्छ ऐप में, आपके पास बहुत सारे रेड्यूसर होंगे, प्रत्येक एक वर्णनात्मक कुंजी के तहत होगा (उदा। 'राज्य' नहीं कहा जाता है, लेकिन आपके डोमेन में चीजों के बाद बुलाया जाता है)। – TomW

5

तो data के अपने mapStateToProps मूल्य एक वस्तु लौटने प्रसारण करने के लिए डिस्पैच पर। आप शायद इस बजाय हैं:

function mapStateToProps(state) { 
    console.log(state); 
    // this console.log shows the state with the data property. 
    return { 
    ...state.app 
    }; 
} 

यह आपको अपनी data कम करने में क्षेत्रों के लिए पहुँच प्रदान करेगा। साथ ही, यह उदाहरण से स्पष्ट नहीं है कि आप डेटा का उपयोग कैसे करेंगे, या इसमें कौन से फ़ील्ड शामिल हैं। साथ ही, आरंभ करने के लिए, आपके रेड्यूसर को उन फ़ील्ड के लिए शून्य या खाली मानों के लिए प्रारंभ नहीं किया गया है, जो निश्चित रूप से त्रुटियों का कारण बन सकते हैं।

const initialState = { 
    error: '', 
    loading: false, 
    data: [] 
}; 

const app = (state=initialState, action) => { 
/* .... */ 
+0

आप सही हैं। आपको ऐसा लगता है कि इसका आधा जवाब मिल गया है। जो मैंने अभी देखा है, सेमा-एसपी ने यह इंगित किया है कि, किसी कारण से, किसी अन्य राज्य वस्तु के अंदर एक राज्य वस्तु निहित होती है। तो बस 'state.state.data' या 'state.state.error' के रूप में बस' state.data' के बजाय दिखाई दे रहा है। यह मेरे reducer के साथ कुछ गलत है, लेकिन मुझे यकीन नहीं है कि क्या। – Jose

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