2017-11-05 2 views
0

In meinem Speicher habe ich einen Zustand mit dieser Form: {posts: [{...},{...}]}, aber wenn ich mapStateToProps() in Home.js verwenden, gibt der Zustand {posts: []}, mit einem leeren Array (wo es ein Array im Zustand des Ladens war) zurück.React/Redux: Warum lässt mapStateToProps() meinen Speicherstatus eines Arrays verschwinden?

Benutzt ich mapStateToProps() falsch oder tritt das Problem von anderen Teilen des Redux-Zyklus auf?

API holen Ich verwende, vorübergehend entfernt in actions.js

// api 

const API = "http://localhost:3001" 

let token = localStorage.token 
if (!token) { 
    token = localStorage.token = Math.random().toString(36).substr(-8) 
} 

const headers = { 
    'Accept': 'application/json', 
    'Authorization': token 
} 

// gets all posts 
const getAllPosts = token => (
    fetch(`${API}/posts`, { method: 'GET', headers }) 
); 

Aktion und Aktion Schöpfer, thunk Middleware:

// actions.js 

export const REQUEST_POSTS = 'REQUEST_POSTS'; 
function requestPosts (posts) { 
    return { 
     type: REQUEST_POSTS, 
     posts 
    } 
} 

export const RECEIVE_POSTS = 'RECEIVE_POSTS'; 
function receivePosts (posts) { 
    return { 
     type: RECEIVE_POSTS, 
     posts, 
     receivedAt: Date.now() 
    } 
} 

// thunk middleware action creator, intervenes in the above function 
export function fetchPosts (posts) { 
    return function (dispatch) { 
     dispatch(requestPosts(posts)) 
     return getAllPosts() 
       .then(
        res => res.json(), 
        error => console.log('An error occured.', error) 
       ) 
       .then(posts => 
        dispatch(receivePosts(posts)) 
       ) 
    } 
} 

Reducer:

// rootReducer.js 

function posts (state = [], action) { 
    const { posts } = action 

    switch(action.type) { 
     case RECEIVE_POSTS : 
      return posts; 
     default : 
      return state; 
    } 
} 

Root-Komponente, die vorübergehend die Redux-Speicher enthält:

// index.js (contains store) 

const store = createStore(
    rootReducer, 
    composeEnhancers(
    applyMiddleware(
     logger, // logs actions 
     thunk // lets us dispatch() functions 
    ) 
) 
) 

store 
    .dispatch(fetchPosts()) 
    .then(() => console.log('On store dispatch: ', store.getState())) // returns expected 

ReactDOM.render(
    <BrowserRouter> 
     <Provider store={store}> 
      <Quoted /> 
     </Provider> 
    </BrowserRouter>, document.getElementById('root')); 
registerServiceWorker(); 

Hauptbestandteil:

// Home.js 
function mapStateToProps(state) { 
    return { 
     posts: state 
    } 
} 


export default connect(mapStateToProps)(Home) 

In Home.js Komponente, console.log('Props', this.props) kehrt {Beiträge: []}, wo erwarte ich {posts: [{...}, {...}]}.

*** EDIT: ein console.log() in der Aktion vor dem Versand und in der Reduktions Nach dem Hinzufügen, hier ist die Ausgabe der Konsole: Console output link (not high enough rep to embed yet)

+0

Alles scheint in Ordnung. Sind Sie sicher, dass Sie Ergebnisse erzielt haben? Können Sie eine "console.log" in Ihre Aktion kurz vor dem Versand und eine in den Reducer setzen? – yuantonito

+0

Gute Idee, ich habe sie hinzugefügt und einen Link auf die Konsolenausgabe oben - scheint die Fetch Returns sind in der Aktion, Reduzierung und Speicher korrekt, aber in der Komponente verschwindet es –

Antwort

2

Der redux Speicher sollte ein Objekt sein, aber scheint, wie es initialisiert zu werden als ein Array im Wurzelreduzierer. Sie können versuchen, die folgenden:

const initialState = { 
    posts: [] 
} 

function posts (state = initialState, action) { 

    switch(action.type) { 
     case RECEIVE_POSTS : 
      return Object.assign({}, state, {posts: action.posts}) 
     default : 
      return state; 
    } 
} 

Dann in Ihrer mapStateToProps Funktion:

function mapStateToProps(state) { 
    return { 
     posts: state.posts 
    } 
} 
+0

Fantastisch, das hat perfekt funktioniert! Danke Grayson! –

Verwandte Themen