私は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>
);
}
}
これは、コードをテストせずに把握するのは難しいものです。 LOAD_SUCCESSアクションが発生した後、コンポーネントでRenderが呼び出されていますか? –
それは、一度しか呼ばれていません –