Ausprobieren React + Redux, und wahrscheinlich mache ich etwas offensichtlich dumm, weil eine Komponente, die eine Aktion zum Abrufen von Daten über das Netzwerk abfeuert nicht aktualisiert (neu gerendert) wird wird geholt.React + Redux: Komponente wird nicht aktualisiert
Hier sind die entsprechenden Bits von meinem Code:
Die Top-Level-index.js als Einstiegspunkt für die Anwendung dienen:
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'));
Top-Level-Container App:
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)
Komponente, die eine Aktion auslöst, um eine Anforderung für Daten zu senden, wenn sie bereitgestellt wird und die abgerufenen Daten anzeigen soll:
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)
Aktion Urheber:
import * as types from '../constants/ActionTypes';
import axios from 'axios';
export function fetchResources() {
return {
type: types.FETCH_FIRST,
payload: axios.get('/sampledata/1.json')
}
}
Reducer für die Aktion holen:
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
}
};
und schließlich die Wurzel Minderer:
import { combineReducers } from 'redux';
import navigationReducer from './navigation-reducer';
import resourcesReducer from './resources-reducer';
const rootReducer = combineReducers({
navigationReducer,
resourcesReducer
});
export default rootReducer;
So, hier ist das, was ich beobachtet werde. Die Aktion zum Anfordern von Daten wird erfolgreich ausgelöst, eine Anforderung wird gesendet, der Reduzierer empfängt sie, wenn das Versprechen aufgelöst wird, und aktualisiert den Status mit den abgerufenen Daten. An dieser Stelle würde ich erwarten, dass die Komponente App
der obersten Ebene und die Komponente Showcase
erkennen, dass der Speicher aktualisiert und erneut gerendert wurde, aber ich sehe ihn nicht in der Konsole.
Auch ich bin von redux-logger
‚s Konsolenausgabe verwirrt:
Insbesondere bin überrascht bin, um zu sehen, dass die state
Reduzierungen von der rootReducer enthält - ich weiß nicht, ob es richtig ist (Ein Beispiel auf Redux logger Github page zeigt einen Zustand ohne Reduzierungen). Es scheint auch überraschend, dass die prev state
, wie von redux-logger
berichtet, enthält resourcesReducer
Objekt als next state
, obwohl ich intuitiv erwarten würde prev state
mehr oder weniger leer.
Könnten Sie bitte darauf hinweisen, was ich falsch mache und wie reagiert React Komponenten auf die state
Änderungen reagieren?
============================================== ====
AKTUALISIERT:
1) Changed die mapStateToProps
Funktion in der App
Komponente, so dass es richtig Staaten abbildet Minderer:
function mapStateToProps(state) {
return {
resources: state.resourcesReducer
}
}
2) immer noch die resources
vorbei nach unten zu die `Showcase-Komponente:
3) Der Versuch, resources
auf dem Bildschirm anzuzeigen, indem es stringifying, um zu sehen, was in diesem Objekt tatsächlich ist:
render() {
console.log('resources', this.props);
return (
<div>
This is showcase {JSON.stringify(this.props.resources)}
</div>
);
}
dies auf dem Bildschirm zu sehen: This is showcase {}
. Die Komponente scheint nicht neu zu rendern.
Hier ist der Screenshot der Konsole, der zeigt, dass App-Requisiten mit den Werten von next state
aktualisiert wurden. AKTUALISIERT
WIEDER: Trotzdem, dass die Komponente neu machen nicht die Ursache Und mein Javascript-fu war schlecht, auch. Ich war mir nicht ganz bewusst, dass ich durch die Rückkehr von Object.assign (state, {resources: action.payload.data });
tatsächlich den Staat mutierte, und dass eine einfache Umkehrung von Argumenten mich das erreichen ließ, was ich beabsichtigte. Danke an this discussion an SO für Aufklärung.
Haben Sie versucht, einen Schlüssel zum Root Reducer-Objekt hinzuzufügen? 'const rootReducer = combineReducers ({ navigation: navigationReducer, resources: resourcesReducer });' – anoop