2016-02-27 23 views
7

के नाम से एक संपत्ति है, मैं रेडक्स और प्रतिक्रिया का उपयोग कर ऐप बना रहा हूं। मैं एक ऐसी समस्या में भाग लेता हूं जहां मैं घटक गुणों के लिए राज्य को मानचित्र नहीं कर सकता क्योंकि राज्य में ऐसी संपत्ति है जो मैंने उपयोग किए गए रेड्यूसर के नाम से मेल खाती है।रेडक्स/प्रतिक्रिया ऐप में राज्य में रेड्यूसर

function mapStateToProps(state) { 
    return { 
    sources: state.sources 
    } 
} 

state.sourcesundefined क्योंकि मूल्य है:

कम कर देता है combineReducers विधि के साथ बनाई गई है

const rootReducer = combineReducers({ 
    appReducer 
}) 

प्रारंभिक अवस्था घटक समारोह mapStateToProps में

const initialState = { 
    sources: [], 
    left: {}, 
    right: {}, 
    diff: {} 
} 

हालांकि हैstate पैरामीटर का

{ 
    appReducer: { 
    sources: [], 
    left: {}, 
    right: {}, 
    diff: {} 
    } 
} 

redux की एक विशेषता यह है है? तो जब मैं अधिक reducers का उपयोग करता हूं तो वे सभी state चर में नई संपत्ति जोड़ देंगे? या मेरे पक्ष में कुछ गड़बड़ है (मैंने कभी भी इस व्यवहार को रेडक्स ट्यूटोरियल्स में कभी नहीं देखा)।

धन्यवाद

+1

आपका कोड सही 'state.appReducer है। स्रोतों के लिए आपको रेड्यूसर नाम –

+3

की कल्पना कीजिए कि आपके पास 2,3 रेड्यूसर हैं, प्रत्येक रेड्यूसर में 'स्रोत' संपत्ति –

+1

है, आप 'state.appReducer द्वारा विशिष्ट 'स्रोत' प्राप्त कर सकते हैं। स्रोत 'और' state.appReducer.2 स्रोत ' –

उत्तर

17

आप केवल एक ही कम करने है, तो आप combineReducers() की जरूरत नहीं है:

combineReducers({ 
    user: userReducer, 
    messages: messagesReducer, 
    notifications: notificationsReducer 
}); 

फिर, अपने राज्य की तरह पहुँचा जा सकता है। बस इसे सीधे का उपयोग करें:

const initialState = { 
    sources: [], 
    left: {}, 
    right: {} 
} 
function app(state = initialState, action) { 
    switch (action.type) { 
    case 'ADD_SOURCE': 
    return Object.assign({}, state, { 
     sources: [...state.sources, action.newSource] 
    }) 
    case 'ADD_SOURCE_TO_LEFT': 
    return Object.assign({}, state, { 
     left: Object.assign({}, state.left, { 
     [action.sourceId]: true 
     }) 
    }) 
    case 'ADD_SOURCE_TO_RIGHT': 
    return Object.assign({}, state, { 
     right: Object.assign({}, state.right, { 
     [action.sourceId]: true 
     }) 
    }) 
    default: 
    return state 
    } 
} 

अब आप कि कम करने के साथ एक दुकान बना सकते हैं:

import { createStore } from 'redux' 
const store = createStore(app) 

और यह करने के लिए एक घटक कनेक्ट:

const mapStateToProps = (state) => ({ 
    sources: state.sources 
}) 

हालांकि अपने कम करने को पढ़ने के लिए मुश्किल है क्योंकि यह एक साथ कई अलग-अलग चीजों को अद्यतन करता है।

function sources(state = [], action) { 
    switch (action.type) { 
    case 'ADD_SOURCE': 
    return [...state.sources, action.newSource] 
    default: 
    return state 
    } 
} 

function left(state = {}, action) { 
    switch (action.type) { 
    case 'ADD_SOURCE_TO_LEFT': 
    return Object.assign({}, state, { 
     [action.sourceId]: true 
    }) 
    default: 
    return state 
    }  
} 

function right(state = {}, action) { 
    switch (action.type) { 
    case 'ADD_SOURCE_TO_RIGHT': 
    return Object.assign({}, state, { 
     [action.sourceId]: true 
    }) 
    default: 
    return state 
    }  
} 

function app(state = {}, action) { 
    return { 
    sources: sources(state.sources, action), 
    left: left(state.left, action), 
    right: right(state.right, action), 
    } 
} 

इस को बनाए रखने और समझने के लिए आसान है, और यह भी आसान बदल सकते हैं और स्वतंत्र रूप से परीक्षण reducers के लिए बनाता है: अब, इस पल आप इसे कई स्वतंत्र reducers में विभाजित करना चाहते हैं।

अंत में, अंतिम चरण के रूप में, हम combineReducers() बजाय हाथ से लिखने की उपयोग कर सकते हैं जड़ app कम करने उत्पन्न करने के लिए:

// function app(state = {}, action) { 
// return { 
//  sources: sources(state.sources, action), 
//  left: left(state.left, action), 
//  right: right(state.right, action), 
// } 
// } 

import { combineReducers } from 'redux' 
const app = combineReducers({ 
    sources, 
    left, 
    right 
}) 

combineReducers() का उपयोग कर के बजाय द्वारा जड़ कम करने लिखने के लिए कोई बड़ा लाभ नहीं है हाथ छोड़कर यह थोड़ा अधिक कुशल है और संभवतः आपको कुछ टाइपो बचाएगा। साथ ही, आप इस ऐप को अपने ऐप में एक से अधिक बार लागू कर सकते हैं: असंबद्ध रेड्यूसर को घोंसले तरीके से कई बार एक रेड्यूसर में गठबंधन करना ठीक है।

यह सभी रिफैक्टरिंग घटकों पर कोई प्रभाव नहीं पड़ेगा।

मैंने तुम्हें अपनी free Egghead course on Redux जो कम करने रचना की इस पद्धति को शामिल किया गया और दिखाता है कि कैसे combineReducers() कार्यान्वित किया जाता है देखने के लिए सुझाव है।

+0

स्पष्टीकरण और उन वीडियो के लिंक के लिए धन्यवाद दान। –

+0

मैं हमेशा आपकी व्याख्या, सरल और सटीक से प्यार करता हूं। –

5

दरअसल, मेरा मानना ​​है कि अपने प्रारंभिक अवस्था होगा: कम करने के नाम पर ले जा रही है, और कहा कि नाम की सामग्री को मैप करके combineReducers काम करता है क्योंकि

{ 
    appReducer: { 
    sources: [], 
    left: {}, 
    right: {}, 
    diff: {} 
    } 
} 

यह वह जगह है।

इसके अलावा, केवल एक नोट, लेकिन यदि आप 1 से अधिक reducer का उपयोग करने जा रहे हैं, तो आपके reducers के नाम appReducer से अधिक विशिष्ट होना चाहिए, और (केवल मेरी व्यक्तिगत राय) उन्हें reducer शब्द की आवश्यकता नहीं है । एक ठेठ एप्लिकेशन को इस प्रकार दिखाई देंगे:

state.user.email 
state.messages[0] 
+0

अपडेट/एक्सेस करने के लिए ऐप रेड्यूसर में "state =itialState.sources" सेट करने की आवश्यकता है। क्या आप सही हैं। क्या मुझे 'प्रारंभिक चरण' बदलना चाहिए तदनुसार ऑब्जेक्ट करें? –

+1

विचार यह है कि रेड्यूसर की प्रत्येक शाखा अपने 'प्रारंभिक स्तर' के लिए ज़िम्मेदार है। आपके रूट रेड्यूसर में कोई प्रारंभिक स्तर नहीं होना चाहिए, और प्रत्येक रेड्यूसर में केवल अपनी सामग्री शामिल होनी चाहिए। इसलिए आपका 'एपरेड्यूसर' कुंजी के साथ एक ऑब्जेक्ट होगा स्रोत, बाएं, दाएं, आदि –

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