2016-07-07 19 views
4

In meiner React Redux-Anwendung, wenn die Hauptseite geladen wird, möchte ich die Daten von einer API abrufen und anzeigen, damit der Benutzer sie sehen kann. Die Daten werden von der Aktion abgerufen und der Status wird aktualisiert. Ich sehe den Staat jedoch nicht als Stütze der Komponente. Nicht sicher, was nicht richtig angeschlossen ist.Redux pass Zustand als Requisiten zu Komponente

Hauptkomponente:

import React, { Component, PropTypes } from 'react'; 
import { connect } from 'react-redux'; 
import { bindActionCreators } from 'redux'; 
import * as actions from '../actions/actions'; 
import '../styles/homeStyles.css'; 

class Home extends Component { 
    constructor(props) { 
    super(props); 
    } 

    componentDidMount() { 
    this.props.actions.fetchMovies(); 
    } 

    render() { 
    const { movies, isFetching, errorMessage } = this.props; 

    if (isFetching && !movies.length) { 
     return <p>Loading...</p>; 
    } 

    //will display movies when I have access to state 
    return (
     <div> 
     <h1>React Starter App</h1> 
     <h2>This is the home page</h2> 
     </div> 
    ); 
    } 
} 

Home.proptypes = { 
    actions: PropTypes.object.isRequired, 
    dispatch: PropTypes.func.isRequired, 
    movies: PropTypes.array.isRequired, 
    isFetching: PropTypes.bool.isRequired, 
    errorMessage: PropTypes.string 
}; 

function mapStateToProps(state) { 
    return { 
    movies: state.movies, 
    isFetching: state.isFetching, 
    errorMessage: state.errorMessage 
    }; 
} 

function mapDispatchToProps(dispatch) { 
    return { actions: bindActionCreators(actions, dispatch) }; 
} 

export default connect(mapStateToProps, mapDispatchToProps)(Home); 

store:

import { createStore, applyMiddleware } from 'redux'; 
import thunkMiddleware from 'redux-thunk'; 
import createLogger from 'redux-logger'; 
import { syncHistoryWithStore } from 'react-router-redux'; 
import { browserHistory } from 'react-router'; 

import rootReducer from '../reducers/index'; 

const initialState = { 
    movies :{ 
    movies: [], 
    isFetching: false, 
    errorMessage: null, 
    firstName: null, 
    lastName: null, 
    email: null 
    } 
}; 

const store = createStore(rootReducer, initialState, applyMiddleware(thunkMiddleware, createLogger())); 

export const history = syncHistoryWithStore(browserHistory, store); 

if (module.hot) { 
    module.hot.accept('../reducers/',() => { 
    const nextRootReducer = require('../reducers/index').default; 
    store.replaceReducer(nextRootReducer); 
    }); 
} 

export default store; 

App:

import React, { Component } from 'react'; 
import Navbar from './Navbar'; 

class App extends Component { 
    render() { 
    return (
     <div> 
     <Navbar /> 
     <div className="container"> 
      {this.props.children} 
     </div> 
     </div> 
    ); 
    } 
} 

export default App; 

Index:

import React from 'react'; 
import {render} from 'react-dom'; 
import { Provider } from 'react-redux'; 
import { Router, Route, IndexRoute } from 'react-router'; 
import store, { history } from './store/store'; 
require('./favicon.ico'); 
import App from './components/App'; 
import Home from './components/Home'; 
import Contact from './components/Contact'; 
import NotFoundPage from './components/NotFoundPage'; 

const router = (
    <Provider store={store}> 
    <Router history={history} > 
     <Route path="/" component={App}> 
     <IndexRoute component={Home} /> 
     <Route path="/contact" component={Contact} /> 
     <Route path="*" component={NotFoundPage} /> 
     </Route> 
    </Router> 
    </Provider> 
); 

render(router, document.getElementById('app')); 

Reducer:

import * as constants from '../constants/constants'; 

const initialState = { 
    movies: [], 
    isFetching: false, 
    errorMessage: null 
}; 

const moviesReducer = (state = initialState, action) => { 
    switch (action.type) { 
    case constants.FETCH_MOVIES : 
     return { 
     ...state, 
     isFetching: true 
     }; 
    case constants.FETCH_MOVIES_SUCCESS : 
     return { 
     ...state, 
     movies: [action.data], 
     isFetching: false 
     }; 
    case constants.FETCH_MOVIES_ERROR : 
     return { 
     ...state, 
     isFetching: false, 
     errorMessage: action.message 
     }; 
    default : 
     return state; 
    } 
}; 

export default moviesReducer; 
+0

Können Sie das Minderer zeigen, wo Filme, nachdem sie aktualisiert werden wird geholt? –

+0

@ Radio- aktualisiert – erichardson30

+0

Setzen Sie einen 'Debugger' in Ihre' mapStateToProps' Funktion. Enthält das eingehende 'state'-Argument die Daten? – lux

Antwort

2

ich zugriff Zustand falsch in meiner mapStateToProps Funktion. Als ich einen Debugger innerhalb der Funktion platzierte, konnte ich die Struktur des Status sehen und es passte nicht zu dem, was ich versuchte, dort zuzugreifen.

Seit meinem Speicher Zustand sah wie folgt aus:

const initialState = { 
    movies :{ 
    movies: [], 
    isFetching: false, 
    errorMessage: null, 
    firstName: null, 
    lastName: null, 
    email: null 
    } 
}; 

ich brauchte, um meine mapStateToProps Funktion in meiner Komponente zu ändern wie folgt aussehen:

function mapStateToProps(state) { 
    return { 
    movies: state.movies.movies, 
    isFetching: state.movies.isFetching, 
    errorMessage: state.movies.errorMessage 
    }; 
} 

Dies alles erlaubt korrekt zugeordnet werden und Zugriff auf den Status innerhalb der Komponente haben.

Seitdem Refactoring ich meinen Zustand im Laden wie folgt aussehen:

const initialState = { 
    movies: { 
    movies: [], 
    isFetching: false, 
    errorMessage: null 
    }, 
    form: { 
    firstName: null, 
    lastName: null, 
    email: null 
    } 
}; 

und meine mapStateToProps funktionieren wie folgt aussehen:

function mapStateToProps(state) { 
    return { 
    movies: state.movies 
    }; 
} 
Verwandte Themen