2016-05-05 15 views
1

私はthis boilerplateを使用していますが、私の状態が更新された後にコンテナが再レンダリングされない問題があります。 1)LOAD - AJAXリクエストの開始時にディスパッチされ、2)LOAD_SUCCESS - データが正常に返されると、2つのアクションがディスパッチされます。ユニバーサル・リアクト/ reduxが状態更新時にレンダリングしない

LOAD_SUCCESSアクションはレデューサーから呼び出されますが、その後は何も起こりません。このコードは数週間前に働いていましたが(プロジェクトは少し保留されていましたが)、もう機能しません。何かご意見は ?

import superagent from 'superagent'; 
import config from '../../config'; 

const LOAD = 'cnnm/sectionFront/LOAD'; 
const LOAD_SUCCESS = 'cnnm/sectionFront/LOAD_SUCCESS'; 
const LOAD_FAIL = 'cnnm/sectionFront/LOAD_FAIL'; 

const initialState = { 
    loaded: false, 
    loading: false, 
    currentSection: null, 
    data: {} 
}; 


export default function reducer(state = initialState, action = {}) { 
    switch (action.type) { 
    case LOAD: 
     return { 
     ...state, 
     loading: true, 
     loaded: false 
     }; 
    case LOAD_SUCCESS: 
     const result = { 
     ...state, 
     loading: false, 
     loaded: true, 
     error: null, 
     currentSection: action.sectionID 
     }; 
     result.data[action.sectionID] = action.data; 
     return result; 
    case LOAD_FAIL: 
     return { 
     ...state, 
     loading: false, 
     loaded: true, 
     data: null, 
     error: action.error 
     }; 
    default: 
     return state; 
    } 
} 


export function load() { 

    return (dispatch, getState) =>{ 

    dispatch({ 
     type: LOAD 
    }); 


    const globalState = getState(); 
    const endpoint = config.endpoints.sectionFronts[globalState.routing.locationBeforeTransitions.pathname]; 

    if (globalState.sectionFront.data[globalState.routing.locationBeforeTransitions.pathname] === undefined){ 
     superagent.get(endpoint) 
     .end((err, resp) => { 
     if (err){ 
      dispatch({ 
      type: LOAD_FAIL, 
      error: err 
      }); 
     } 
     else { 

      try { 
      const data = JSON.parse(resp.text); 
      dispatch({ 
       type: LOAD_SUCCESS, 
       sectionID: globalState.routing.locationBeforeTransitions.pathname, 
       data 
      }); 
      } 
      catch (error){ 
      console.warn('Error trying to parse section front', error); 
      dispatch({ 
       type: LOAD_FAIL, 
       error: error 
      }); 
      } 

     } 

     }); 

    } 
    else { 
     // Already have the data cached 
     dispatch({ 
     type: LOAD_SUCCESS, 
     sectionID: globalState.routing.locationBeforeTransitions.pathname, 
     data: globalState.sectionFront.data[globalState.routing.locationBeforeTransitions.pathname] 
     }); 
    } 
    }; 

} 

コンテナコード:http://redux.js.org/docs/FAQ.html#react-not-rerenderingでReduxのFAQ当たり

import React, {Component, PropTypes} from 'react'; 
import {connect} from 'react-redux'; 
import Helmet from 'react-helmet'; 
import Col from 'react-bootstrap/lib/Col'; 
import Row from 'react-bootstrap/lib/Row'; 
import { asyncConnect } from 'redux-async-connect'; 
import { load as loadSectionFront } from 'redux/modules/sectionFront'; 
import {bindActionCreators} from 'redux'; 
import { Loading } from 'components'; 


import Grid from 'react-bootstrap/lib/Grid'; 
import { cards as cardComponents } from 'components'; 

@asyncConnect([{ 
    deferred: true, 
    promise: ({store: {dispatch, getState}}) => { 
    return dispatch(loadSectionFront()); 
    } 
}]) 

@connect(
    state => { 
    return { 
     section: state.sectionFront.data, 
     currentSection: state.sectionFront.currentSection, 
     loaded: state.sectionFront.loaded, 
     loading: state.sectionFront.loading 
    }; 
    }, 
    dispatch => bindActionCreators({loadSectionFront}, dispatch) 
) 

export default class SectionFront extends Component { 

    static propTypes = { 
    section: PropTypes.object, 
    loaded: PropTypes.bool, 
    loading: PropTypes.bool, 
    currentSection: PropTypes.string, 
    loadSectionFront: PropTypes.func, 
    } 

    mapSecionNameToPrettyName = (sectionID) => { 

    switch (sectionID){ 

     case '/': 
     return 'Top News'; 
     case '/video': 
     return 'Video'; 
     case '/technology': 
     return 'Technology'; 
     case '/media': 
     return 'Media'; 
     case '/investing': 
     return 'Investing'; 
     case '/news/economy': 
     return 'Economy'; 
     case '/pf': 
     return 'Personal Finance'; 
     case '/retirement': 
     return 'Retirement'; 
     case '/autos': 
     return 'Autos'; 
     case '/smallbusiness': 
     return 'Small Business'; 
     case '/news/companies': 
     return 'Companies'; 
     case '/luxury': 
     return 'Luxury'; 
     case '/real_estate': 
     return 'Real Estate'; 
     default: 
     return 'Not found'; 
    } 
    } 

    render() { 
    const {section, loaded, currentSection, loading } = this.props; 
    const sectionName = this.mapSecionNameToPrettyName(currentSection); 
    const styles = require('./SectionFront.scss'); 

    let cardNodes = ''; 
    if (loaded){ 
     cardNodes = section[currentSection].cards.map((card, index) => { 

     switch (card.cardType) { 
      case 'summary': 
       if (card.images === undefined || card.cardStyle === 'text'){ 
       return <cardComponents.SummaryTextComponent card={card} key={index} />; 
       } 
       else { 
       if (card.cardStyle === 'default'){ 
        return <cardComponents.SummaryDefault card={card} key={index} />; 
       } 
       else if (card.cardStyle === 'jumbo' || card.cardStyle === 'jumboBlack'){ 
        return <cardComponents.SummaryJumboComponent card={card} key={index} />; 
       } 
       else if (card.cardStyle === 'jumboOverlay'){ 
        return <cardComponents.SummaryJumboOverlayComponent card={card} key={index} />; 
       } 
       } 
      break; 

      case 'marketIndices': 
      return <cardComponents.MarketIndicesComponent key={index} />; 

      case 'ad': 
      return <cardComponents.AdComponent card={card} key={index} />; 

      case 'bizDev': 
      return <cardComponents.BizDevComponent card={card} key={index} />; 

      default: 
      return (<div key={index}> </div>); 
     } 

     }); 
    } 

    return (
     <div className={styles.sectionFront}> 
     { loading ? <div className={styles.overlay}><Loading /></div> : null } 
     <Grid className={styles.container}> 
      <Row className={styles.sectionTitle}> 
      <Col className={ 'col-xs-12 ' + styles.sectionCol}> 
       <h1 className="container">{sectionName}</h1> 
      </Col> 
      </Row> 
      {cardNodes} 
     </Grid> 

     </div> 
    ); 
    } 
} 
+0

これは、コードをテストせずに把握するのは難しいものです。 LOAD_SUCCESSアクションが発生した後、コンポーネントでRenderが呼び出されていますか? –

+0

それは、一度しか呼ばれていません –

答えて

0

、時間の99.9%は、コンポーネントが再レンダリングではない理由は、直接状態を変異減速です。この行はちょうどそれをやっているようです:result.data[action.sectionID] = action.data;。クローズドバージョンのdataresultの中に戻す必要があります。

「データ」参照が同じままであっても、「読み込み」と「読み込み」の変更によってコンポーネントが正しく再描画されることが実際には予想されますが、ここには欠けている。

関連する問題