2015-12-15 24 views
5

Ho il mio stato in Redux e sto usando il connettore react-redux per legarlo alla mia applicazione React. Durante la prima esecuzione in cui è impostato lo stato, la connessione funziona alla grande. Tuttavia, quando aggiorno una parte dello stato nel mio riduttore, non viene letto come modificato da React, quindi il componente non esegue nuovamente il rendering. Quando faccio qualche altra azione che costringe un rendering, lo stato è stato, in realtà, cambiato.React non si aggiorna quando lo stato di Redux viene modificato sotto il primo livello

Sembra avere a che fare con lo stato non essendo riconosciuti come aver cambiato e, nel metodo wrapWithConnect di reagire-redux, lo storeChanged e propsChanged entrambi restituiscono false dopo l'esecuzione iniziale attraverso. Un indizio potrebbe essere essere che reagisce-redux si confronta a un livello superficiale in quei controlli.

La domanda è: "quello che devo fare per ottenere Reagire per visualizzare modifiche al mio stato quando cambia lo stato di Redux"?

La parte rilevante dello stato è al di sotto

let thisOrder = Immutable.fromJS({ 
"projectNumber": '', 
"orderHeader": { 
    "order_id": "", 
    "firstname": "", 
    "lastname": "", 
    "address1": "", 
), 
"orderProducts": [], 
"lastOperation": ''}); 

La sezione che viene aggiornato è orderProducts, una vasta gamma di prodotti che si presenta fondamentalmente come

orderProducts:[{productSKU:'Y54345',productDesc:'What it is',price:"4.60",qty:2}, 
{productSKU:'Y54345',productDesc:'What what is',price:"9.00",qty:1}] 

Durante l'aggiornamento qty o il prezzo nel riduttore sotto (chiamato da un'azione) il risultante newState ha le modifiche

case OrderConstants.ORDER_PRODUCT_UPDATE:{ 

let productList = updateProductList(action.updateProduct, state.get(
'orderProducts')) 

let newState = state.update('orderProducts', 
productList).set('lastOperation', action.type); 

    return newState;} 
.210

Infine, il controllo React componente che quindi invia i puntelli valle

render: function() { 
     return (
      <div> 
       <ProductList updateOrder={this.updateOrder()} products={this.props.products}/> 

        {this.submitContinueButton()} {this.submitButton()} 
        {this.cancelButton()} 
       </div> 
      </div> 
     ) 
    } 
}); 
// connect to Redux store 
var mapStateToProps = function (state) { 
    return { ocoStore: state.toJS(), 
      products: state.get('orderProducts')}; 
}; 

export default connect(mapStateToProps)(OrderProducts); 

Tutto quanto sopra viene tagliato le relative sezioni. Si noti che il codice funziona per visualizzare le informazioni sul prodotto sui componenti inferiori durante il caricamento iniziale. È quando si aggiorna il prezzo o qty che l'aggiornamento non si verifica.

+0

Puoi fornire il codice per il tuo metodo 'updateProductList'? – DDA

risposta

1

Ho replicato la soluzione utilizzando JSBIN e sono riuscito a farlo funzionare, quindi ho pensato di condividerlo nel caso in cui ti aiuta in qualche modo.

Di seguito è riportato il codice visualizzato in JSBIN. È basato sui frammenti di codice nella tua domanda. Nota che non hai fornito il codice per il tuo metodo updateProductList e il codice per il componente ProductList quindi ho dovuto crearne uno mio.

const initialState = Immutable.fromJS({ 
    "projectNumber": '', 
    "orderHeader": { 
    "order_id": "", 
    "firstname": "", 
    "lastname": "", 
    "address1": "", 
    }, 
    "orderProducts": [ 
    { 
     productSKU: 'Y54345', 
     productDesc: 'What it is', 
     price: "4.60", 
     qty:2 
    }, 
    { 
     productSKU: 'Y54346', 
     productDesc: 'What what is', 
     price:"9.00", 
     qty:1 
    } 
    ], 
    "lastOperation": '' 
}); 


const updateProductList = (updateProduct, productList) => { 
    return productList.map(product => { 
    if (product.get('productSKU') === updateProduct.productSKU) { 
     return Immutable.fromJS(updateProduct); 
    } 
    return product; 
    }); 
}; 

const order = (state = initialState, action) => { 
    switch (action.type) { 
    case 'ORDER_PRODUCT_UPDATE': 
     let updatedProductList = updateProductList(action.updateProduct,state.get('orderProducts')); 

     const newState = state.set('orderProducts', updatedProductList).set('lastOperation', action.type); 

     return newState; 
    default: 
     return state; 
    } 
}; 

const { combineReducers } = Redux; 
const orderApp = combineReducers({ order }); 

const { Component } = React; 
const { Provider, connect } = ReactRedux; 

const ProductList = ({ 
    products 
}) => { 
    return (<ul> 
      {products.map(product => { 
      return (
      <li key={product.get('productSKU')}> 
       {product.get('productSKU')} - {product.get('productDesc')} - {product.get('qty')} 
      </li> 
      ); 
      } 
     )} 
     </ul>); 
}; 

const OrderProducts = ({ 
    ocoStore, 
    products, 
    dispatch 
}) => (
       <div> 
       <ProductList products={products} /> 
       <a href='#' 
        onClick={e => { 
        e.preventDefault(); 
        dispatch({ 
         type: 'ORDER_PRODUCT_UPDATE', 
         updateProduct: { 
         productSKU: 'Y54345', 
         productDesc: 'What it is', 
         price: "4.60", 
         qty: 8 
         } 
        }); 
       }}>Update Product Y54345</a> 
      </div> 
) 

const mapStateToProps = (state) => { 
    return { 
     ocoStore: state.order.toJS(), 
     products: state.order.get('orderProducts') 
    }; 
}; 

const OrderApp = connect(mapStateToProps)(OrderProducts); 

const { createStore } = Redux; 

ReactDOM.render(
    <Provider store={createStore(orderApp)}> 
    <OrderApp /> 
    </Provider>, 
    document.getElementById('root') 
); 

JSBIN: http://jsbin.com/qabezuzare

La parte nel mio codice che differisce è il seguente:

const newState = state.set('orderProducts', updatedProductList).set('lastOperation', action.type); 

Questo perché il mio metodo updateProductList restituisce un nuovo Immutable.List.

Spero di guardare la soluzione di lavoro che ti aiuterà a risolvere il tuo problema.

Problemi correlati