2016-08-26 3 views
1

Ich versuche, einige lokale JSON-Daten mit Redux zu laden und in react app anzuzeigen. Aber ich bekomme die pageId is undefined im Reducer.Anzeige von JSON-Daten mit Reagieren und Reduzieren

Nicht sicher, was ich hier falsch mache, ich denke, es könnte etwas falsch sein, wie ich die Daten weitergeben, aber ich bin sehr neu zu redux, also bin ich mir nicht sicher.

Daten

const page = [ 
    {"title":"Mollis Condimentum Sem Ridiculus"}, 
    {"title":"Pharetra Tellus Amet Commodo"} 
] 
export default page; 

Aktion

const getPage = (pageId) => { 
    const page = { pageId: pageId } 
    return { 
     type: 'GET_PAGE_SUCCESS', 
     payload: page 
    } 
} 
export default getPage 

Reducer

import getPage from '../actions/actionCreators' 
import pageData from './../data/pageData'; 


const defaultState = pageData 

const pageReducer = (state = defaultState, action) => { 
    if (action.type = 'GET_PAGE_SUCCESS') { 
     state.page[action.payload.pageId].title = action.payload 
    } 

    return state 
    } 

    export default PageReducer 

Komponente

import React, { Component, PropTypes } from 'react' 
import { connect } from 'react-redux' 
import getpage from '../../actions/actionCreators' 

const mapStateToProps = (state, props) => { 
    const page = state.page[props.pageId] 
    return { page } 
} 

class Page extends Component { 
    componentDidMount() { 
     this.props.getpage(this.props.pageId) 
    } 

    render() { 

     return (<div><PageContainer pageId={0} /></div>) 
    } 
    } 

    const PageContainer = connect(mapStateToProps, { getpage })(page) 

    export default Page 

Antwort

1

Hey ich sehe einen kleinen Fehler in Ihrer Komponente, denke ich. Sie tun this.props.pageId, wenn Sie Seite und nicht pageId auf den Requisiten der Komponente einstellen. Also sollte es nicht this.props.getPage(this.props.page.pageId) stattdessen sein? Könnte es das sein?

Auch eine kleine Randnotiz, ein wichtiger Tipp für die Verwendung von Redux ist nicht mutieren Zustand. In Ihnen Reducer, wo Sie tun, state.page[action.payload.pageId].title = action.payload sollten Sie wahrscheinlich nicht so Zustand setzen, sondern stattdessen ein neues Objekt namens newState, die mit Zustand identisch ist, aber mit dem Titel aktualisiert. Es ist wichtig, Objekte in Redux als unveränderbar zu behandeln. Prost

+0

Danke, ich gab Ihren Vorschlag, die Komponente zu aktualisieren und immer noch das gleiche Problem zu bekommen. Aufgrund Ihres anderen Kommentars vermute ich, dass ich auch etwas anderes falsch verstanden habe. Lernen ist schwer! – Ash

+0

@Ash, viel Glück! –

1

Ich habe den Code in einen Arbeits JSFiddle Referenz geändert: https://jsfiddle.net/qodof048/11/

Ich habe versucht, es so nah an Ihrem Beispiel zu halten, aber lassen Sie mich die Änderungen erklären ich es (auch bekommen gemacht zu arbeiten beachten Sie, dass JSFiddle verwendet nicht die ES6-Import-Syntax).

1) Ihr PageContainer wurde nicht korrekt erstellt. Der letzte Parameter sollte eine Referenz auf die Page-Komponente (nicht 'Seite') gewesen sein.

const PageContainer = connect(mapStateToProps, { getPageSimple, getPageAsync })(PageComponent) 

2) verwendeten Sie PageContainer in der Seite Komponente, aber PageContainer ist der 'Wrapper' um Seite. Sie verwenden PageContainer anstelle von Page in Ihrer Rendermethode, sodass die Daten geladen werden (Kartenstatus und Aktionen).

3) Der Laden war ein wenig durcheinander. Wenn ich Ihr Beispiel richtig verstanden habe, möchten Sie eine Seite aus dem Array pageData in den lokalen Speicher laden, der möglicherweise einen Serveraufruf simuliert. In diesem Fall kann "dirialState" nicht pageData sein, sondern ist ein leeres Objekt. Stellen Sie sich das wie eine lokale Datenbank vor, die Sie ausfüllen werden. Der Aufruf Ihrer Aktion getPage ruft dann die Seite (hier von Ihrem Array) ab und versendet sie in den Store, der sie dort speichert.

const getPageSimple = (pageId) => { 
    const page = pageDatabase[pageId]; // this call would be to the server 

    // then you dispatch the page you got into state 
    return { 
    type: 'GET_PAGE_SUCCESS', 
    payload: { 
     id: pageId, 
     page: page 
    } 
    } 
} 

4) Ich habe ein asynchrones Beispiel zum JSFiddle hinzugefügt zu erklären, wie würden Sie die Seite vom Server tatsächlich holen (da das einfache Beispiel nicht ausreichen würde). Dies benötigt die Thunk-Middleware, damit redux funktioniert (da Sie Zugriff auf die Dispatch-Methode benötigen, um sie asynchron aufzurufen). SetTimeout simuliert einen Anruf mit langer Laufzeit.

const getPageAsync = (pageId)=>{ 
    return (dispatch, getState) => { 
    setTimeout(()=>{ 

     const page = pageDatabase[pageId]; // this call would be to the server, simulating with a setTimeout 
     console.log("dispatching"); 
     // then you dispatch the page you got into state 
     dispatch({ 
     type: 'GET_PAGE_SUCCESS', 
     payload: { 
      id: pageId, 
      page: page 
     } 
     }); 
    }, 2000); 
    } 
} 

Die JSFiddle Lasten 2-Container, ein mit Ihrem einfachen getPage und ein mit der Asynchron-Version, die den Titel nach 2 Sekunden geladen werden.

Hoffe, dass Sie auf Ihrer Reaktion/redux Reise hilft.

Verwandte Themen