2015-10-24 5 views
7

मैं अभी भी विभाजित reducers को बनाए रखने के दौरान अपने राज्य के पेड़ पर कई शीर्ष स्तर के क्षेत्रों को अद्यतन करने के लिए आदर्श तरीका काम करने की कोशिश कर रहा हूँ।विभाजित reducers के साथ संबंधित राज्य क्षेत्रों को अद्यतन करने का सबसे अच्छा तरीका?

यहां एक आसान समाधान है जिसके साथ मैं आया हूं।

var state = { 
    fileOrder: [0], 
    files: { 
    0:{ 
     id: 0, 
     name: 'asdf' 
    } 
    } 
}; 

function handleAddFile(state, action) { 
    return {...state, ...{[action.id]:{id: action.id, name: action.name}}}; 
}; 

function addFileOrder(state, action) { 
    return [...state, action.id]; 
} 

// Adding a file should create a new file, and add its id to the fileOrder array. 
function addFile(state, action) { 
    let id = Math.max.apply(this, Object.keys(state.files)) + 1; 
    return { 
    ...state, 
    fileOrder: addFileOrder(state.fileOrder, {id}), 
    files: handleAddFile(state.files, {id, name: action.name}) 
    }; 
} 

वर्तमान में मैं केवल एक कार्रवाई {type: ADD_FILE, fileName: 'x'} प्रेषण करने में सक्षम हूँ, तो addFile आंतरिक रूप से एक कार्रवाई बनाता addFileOrder और addFile को भेजना चाहिए।

मुझे उत्सुकता है यदि इसे नीचे से किसी एक को करने का बेहतर तरीका माना जाता है।

इसके बजाय दो क्रियाएं प्रेषित करें, एक फ़ाइल जोड़ने के लिए, फिर इसे आईडी प्राप्त करें और आईडी के साथ ADD_TO_FILE_ORDER कार्रवाई भेजें। या नई आईडी की गणना करने के लिए addFile की अनुमति देने के बजाय {type: ADD_FILE, name: 'x', id: 1} जैसे आग और कार्रवाई। यह मुझे combineReducers का उपयोग करने और क्रिया प्रकार पर फ़िल्टर करने की अनुमति देगा। यह उदाहरण शायद मामूली है, लेकिन मेरा वास्तविक राज्य पेड़ थोड़ा और जटिल है, प्रत्येक फ़ाइल को जोड़ने के साथ-साथ अन्य इकाइयों में भी जोड़ा जाना आवश्यक है।

कुछ अतिरिक्त संदर्भ के लिए, एक और पूर्ण राज्य पेड़ इस तरह दिखेगा।

{ 
    "fileOrder": [0] 
    "entities": { 
     "files": { 
      0: { 
       id: 0, 
       name: 'hand.png' 
      } 
     }, 
     "animations": { 
      0: { 
       id: 0, 
       name: "Base", 
       frames: [0] 
      } 
     }, 
     "frames": { 
      0: { 
       id: 0, 
       duration: 500, 
       fileFrames: [0] 
      } 
     }, 
     "fileFrames": { 
      0: { 
       id: 0, 
       file: 0, 
       top: 0, 
       left: 0, 
       visible: true 
      }   
     } 
    } 
} 

की आवश्यकता होगी करने के लिए फ़ाइल जोड़ना:

  1. फ़ाइलों हैश करने के लिए इसे जोड़ें।
  2. इसे फ़ाइल ऑर्डर सरणी में जोड़ें।
  3. फ़ाइल जोड़ें प्रत्येक फ़ाइल के लिए फ़ाइल का संदर्भ देने वाला फ्रेम।
  4. प्रत्येक नई फ़ाइल को उस फ्रेम में जोड़ें जिसे फ्रेम के लिए बनाया गया था।

अंतिम दो बिंदु मुझे आश्चर्यचकित करते हैं अगर मैं combineReducers का उपयोग करने में सक्षम हूं।

उत्तर

7

मुझे इस समस्या का एक बहुत ही सरल समाधान मिल गया।

दस्तावेज से ये दोनों ब्लॉक कार्यात्मक रूप से एक ही चीज़ हैं।

const reducer = combineReducers({ 
    a: doSomethingWithA, 
    b: processB, 
    c: c 
}); 

// This is functionally equivalent. 
function reducer(state, action) { 
    return { 
    a: doSomethingWithA(state.a, action), 
    b: processB(state.b, action), 
    c: c(state.c, action) 
    }; 
} 

मैं दूसरे ब्लॉक को ट्विकिंग कर रहा था, और हमेशा अपने वैश्विक राज्य के पेड़ के साथ गुजर रहा था। जब तक कुछ भी राज्य को रास्ते में संपादित नहीं करता है, तब तक सभी reducers ठीक काम करते हैं। लेखक के समाधान के

// Simple change to pass the entire state to each reducer. 
// You have to be extra careful to keep state immutable here. 
function reducer(state, action) { 
    return { 
    a: doSomethingWithA(state.a, action, state), 
    b: processB(state.b, action, state), 
    c: c(state.c, action, state) 
    }; 
} 
2

भवन:

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

यदि अन्य डेवलपर्स अपने कोड के साथ आरक्षित नहीं हैं तो यह अशुद्धता पागल हो सकती है। कल्पना करें कि क्या होगा यदि राज्य के बी और सी के हिस्से को बदलना शुरू हो जाए, बी और ए के हिस्से को बदलना, और इसी तरह।

आप इस तरह अशुद्धता की सतह क्षेत्र सिकुड़ पर विचार हो सकता:

function reducer(state, action) { 
    return { 
    a: doSomethingWithA(state.a, action, state.globals), 
    b: processB(state.b, action, state.globals), 
    c: c(state.c, action, state.globals) 
    }; 
} 
संबंधित मुद्दे