React + Reduxを試してみると、ネットワーク上でデータを取得するアクションを起動するコンポーネントがデータフェッチされます。React + Redux:コンポーネントが更新されない
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, browserHistory } from 'react-router';
import reduxPromise from 'redux-promise';
import createLogger from 'redux-logger';
const logger = createLogger();
import routes from './routes';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware(reduxPromise, logger)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router history={browserHistory} routes={routes} />
</Provider>
, document.querySelector('.container'));
トップレベルのコンテナアプリケーション:
import React, {Component} from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as Actions from '../actions';
import Header from '../components/header';
import Showcase from '../components/showcase';
function mapStateToProps(state) {
return {
resources: state.resources
}
}
function mapDispatchToProps(dispatch) {
return {
fetchResources:() => {
dispatch(Actions.fetchResources());
}
}
}
class App extends Component {
render() {
console.log('props in App', this.props);
return (
<div>
<Header/>
<Showcase
fetchResources={this.props.fetchResources}
resources={this.props.resources}
/>
</div>
);
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)
アプリのエントリポイントとして
トップレベルのindex.js:ここ
は、私のコードの関連するビットです
アクションをトリガするコンポーネントは、マウントしようとしているときにデータの要求を送信し、取得したデータを表示するはずです。
import React, {Component} from 'react';
import {connect} from 'react-redux';
class Showcase extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.props.fetchResources();
}
render() {
console.log('resources', this.props);
return (
<div>
This is showcase
</div>
);
}
}
export default connect(state => ({resources: state.resources}))(Showcase)
アクション作成者:フェッチアクションの
import * as types from '../constants/ActionTypes';
import axios from 'axios';
export function fetchResources() {
return {
type: types.FETCH_FIRST,
payload: axios.get('/sampledata/1.json')
}
}
リデューサー:
import * as types from '../constants/ActionTypes';
export default function resourcesReducer (state={}, action) {
switch (action.type) {
case types.FETCH_FIRST:
console.log('about to return', Object.assign (state, {resources: action.payload.data }))
return Object.assign (state, {resources: action.payload.data });
default:
return state
}
};
、最終的にはルート減速:だから、ここ
import { combineReducers } from 'redux';
import navigationReducer from './navigation-reducer';
import resourcesReducer from './resources-reducer';
const rootReducer = combineReducers({
navigationReducer,
resourcesReducer
});
export default rootReducer;
は、私が観察していますものです。データを要求するアクションは正常にトリガーされ、要求が送信され、約束が解決されるとレデューサーはそれを受け取り、フェッチされたデータで状態を更新します。この時点で、トップレベルのApp
コンポーネントとShowcase
コンポーネントが、ストアが更新されたことを検出して再レンダリングすることを期待しますが、コンソールには表示されません。
はまた、私はredux-logger
のコンソール出力で混乱しています:
は具体的に、私はstate
がrootReducerから減速が含まれていることを確認するために驚いています - それが正しいかどうかはわかりません( Redux logger Github pageの例では、減速器のない状態を示しています)。直感的に私はprev state
が多かれ少なかれ空であると予想しているが、redux-logger
によって報告されたprev state
が同じresourcesReducer
オブジェクトを含むことも驚くようである。
私が間違っていることを指摘し、どのように反応コンポーネントがstate
の変更に応答するのか教えてください。
============================================== ====
を更新:
1)が正しく状態を減速するためにマップするようApp
成分でmapStateToProps
機能を変更:
function mapStateToProps(state) {
return {
resources: state.resourcesReducer
}
}
2)さらにまでresources
を渡しますショーケースコンポーネント:
render() {
console.log('props in App', this.props);
return (
<div>
<Header navigateActions={this.props.navigateActions}/>
React simple starter
<Showcase
fetchResources={this.props.fetchResources}
resources={this.props.resources}
/>
</div>
);
3)このオブジェクトの内部で実際に何があるか確認するために、それを文字列化して、画面上のresources
を表示しようとすると:
render() {
console.log('resources', this.props);
return (
<div>
This is showcase {JSON.stringify(this.props.resources)}
</div>
);
}
画面上でこれを参照してください:This is showcase {}
。コンポーネントが再レンダリングされていないようです。ここで
は、Appの小道具はnext state
からの値で更新していることを示すコンソールのスクリーンショットです。それでも、そのコンポーネントを再レンダリングすることはありませんでした:
再び更新:そして、私のjavascript-FUも不良でした。 Object.assign (state, {resources: action.payload.data });
私は実際に国家に突然変異を起こしていましたが、単純な議論の逆転が私の意図したものを達成することができたと思います。啓発のためにSOのthis discussionに感謝します。
ルートレデューサーオブジェクトにキーを追加しようとしましたか? 'のconst rootReducer = combineReducers({ ナビゲーション:navigationReducer、 資源:resourcesReducer });' – anoop