2015-11-16 10 views
9

Redux için ToDo örneğine benzer şekilde, proje yapmam benzerdir - yalnızca görüntülenecek alt öğe bileşenlerine sahip bir kapsayıcıdır. mağaza aşağıdaki gibi görünecektir:Yuvalanmış Redux akıllı bileşenleri redüktörlerle bağlama

{ 
    workspace: { 
     widgets: [1, 2, 3] 
    } 
    widgets: { 
     1: { 
      id: 1, 
      title: 'First Widget', 
      lastPrice: 123.324, 
      lastUpdate: '2015-11-12' 
     }, 
     2: { 
      id: 2, 
      title: 'Second Widget', 
      lastPrice: 1.624, 
      lastUpdate: '2015-11-12' 
     }, 
     3: { 
      id: 3, 
      title: 'Third Widget', 
      lastPrice: 4.345, 
      lastUpdate: '2015-11-12' 
     } 
    } 
} 

her widget öğesi, kendi başına bir kompleks bileşenidir - olası eylemler, birçok özellikleri ve birçok çocuk dilsiz bileşenlerin bir sürü. Bu nedenle, her bir widget'ı, bu durum değişikliklerini ayrı tutmak için özel bir WidgetReducer'e sahip bağlı bir akıllı bileşen yaptım.

Ben WidgetReducer istediğiniz bir seferde sadece bir widget'la endişelenmek için, bu yüzden onun tarafından işlenen devlet gibi tek Widget düğümü olacaktır: Şu anda yineler yerinden

{ id: 3, 
    title: 'Third Widget', 
    lastPrice: 4.345, 
    lastUpdate: '2015-11-12' 
} 

My Çalışma Alanı bileşeni Radyo, her Araç akıllı bileşene Araç ID geçen:

@connect((state, ownProps) => ({ widget: state.widgets[ownProps.widgetId]})) 
export default class Widget extends React.Component { 
    componentWillMount() { 
     this.props.dispatch(subscribeToUpdates(this.props.widgetId)); 
    } 

    render() { 
     return (
      <div> 
       <header>{this.props.widget.title}</header> 
       <div> /* Other widget stuff goes here */</div> 
      </div> 
     ); 
    } 
} 
0:

@connect(state => ({ workspace: state.workspace })) 
export default class Workspace extends React.Component { 
    render() { 
     return (
      <div> 
       {this.props.workspace.widgets.map(id => 
        (<Widget key={id} widgetId={id} />) 
       )} 
      </div> 
     ); 
    } 
} 

Termometrem bileşeni çok gibidir

Her bir Widget bileşenini, yalnızca kendi Widget nesnesinde durum güncellemelerini alabilmesi için nasıl bağlayabilirim ve bağlı Widget Redüktör yalnızca bir koleksiyondan ziyade ayrı Widget nesneleriyle ilgilenir? Her şeyden

+0

Biraz daha detaylandırır mısınız? Bir redüktör, yalnızca eylemleri almaz. Sorunuz biraz belirsiz ... İhtiyacınız olan veri dilimlerini içeren bir özelliği olan bir eylemi gönderebilirsiniz ... İstediğiniz şeyin bu olduğundan emin değilsiniz. – Seneca

+0

Açıklığa kavuşturmaya çalıştım ... eğer hala açık değilse bana bildirin! Teşekkürler. – Marcus

+0

@Seneca sadece bir redüktörün bir durum ve bir eylemi ele geçirip yeni bir duruma yol açan saf bir işlev olduğunu belirtmek istedi. https://github.com/rackt/redux#the-gist – Joe

cevap

4

İlk yeniden seçmek bakmak: Soruyu anlamak https://github.com/rackt/reselect

, bu aradığınız budur. Widget-kimliği 2'nin değiştiğini, widget 1'in ve widget 3'ün widget 2'nin durumunu değiştirmediğini varsayalım. Yalnızca widget 2'nin bu değişikliği yansıtması gerekiyor. Yeniden seç, size 'hafızaya alınmış' seçme işlevlerini oluşturma gücü verir. Bu, süslü bir kelime gibi görünebilir, ancak pratikte, bir seçicinin girdi değeri değiştiğinde, bir sonraki durumu hesaplayacağı anlamına gelir.

Widget örneğinde, yalnızca ilgili devlet dilimi değiştiyse durumu yeniden hesaplayan belirli işlevler oluşturabilirsiniz.

Olası örnek:

import { createSelector } from 'reselect' 

const widgetByIdSelector = (state, props) => state.widgets[props.widgetId] 
// this is the `input` function for you selector: as input we take the 
// specific slice of state a specific widgetId requests. 
// the main idea is: only if the `input` of this function changes, it'll 'reselect' that state. 

export const widgetSelector = createSelector(
    widgetByIdSelector, 
    (widgetById) => { 
     return { widgetById } 
    } 

@connect(widgetSelector) 
export default class Widget extends Component { ... } 

bu kod çalışacaktır eğer titrek internet bağlantısı olan bir tren yolculuğu bu yazdım, hiçbir fikrim yok, ama bu temel fikir ... gelince

bir redüktör & eylem yaratıcıları (muhtemelen böyle bir şey yaptığını edeceğiz):

export function createActionForSpecificWidgetById(widgetId, payload) { 
    return { 
     type: ACTIONS.HERE_COMES_YOUR_ACTION_TYPE, 
     widgetId, 
     payload 
    } 
} 

function reducer(state = initialState, action) { 
    switch(action.type) { 
    case HERE_COMES_YOUR_ACTION_TYPE: 
     //now you can modify the state of the specific widgetId because you have access to the id at action.widgetId 
} 

bu aradığın şey bu mu?

+0

Bu oldukça yararlı ve evet, Reselect kesinlikle yardımcı olacaktır.Sorunun ikinci kısmına tam olarak cevap vermez - redüktörden geçip iade edilen devlet, tek bir widget nesnesi olmak istiyorum, spesifik özümü çıkarmak için ihtiyacım olan tüm widget'lardan oluşan bir koleksiyon olmak istiyorum. kimliğine göre widget. Bunun gerçekten mümkün olmadığını düşünmeye başladım mı? – Marcus

+0

Daha fazla düşündüğünüzde, bu teknik olarak mümkün olabilir, ancak sonuç, widget'lar koleksiyonunun bir koleksiyonuna sahip olacaktır. Bu durumda, sonuçlar daha sonra mağazadaki (örneğin, dokümanlar) (http://rackt.org/redux/docs/basics/DataFlow.html)). Güzel değil, gerekli değil. Sadece benim newbie nasıl çalıştığını anlatan Redux nasıl çalışır :) – Marcus

+0

böylece birleştirmekReducers ({widgets: combineReducers ({widget1: widgetReducer1, widget2: widgetReducer2, widget2: widgetReducer3}})? Şimdi senin devletin {widget: {widget1: gibi görünüyor {}, widget2: {}, widget3: {}} – Seneca