2016-04-20 15 views
0

Ich erhalte die folgende Fehlermeldung, wenn meine Seite rendert (Client-Seite)Erste Fehler, auch wenn die Seite rendert

Uncaught (in promise) TypeError: Cannot read property 'asMutable' of undefined

Die Seite korrekt obwohl macht „Can not Eigenschaft‚asMutable‘undefinierter lesen“, also kann ich nur annehmen, dass die Komponente die Anfrage nach dem Rendern erneut stellt, es bricht nichts (bisher), es ist nur ein ärgerlicher Fehler, aber während ich versuche, React zu lernen, wäre es hilfreich zu wissen, warum dies geschah .

Hier ist mein Code:

//nav.jsx 

import React from 'react'; 
import { Link } from 'react-router'; 
import { connect } from 'react-redux'; 
import { navLoad } from '../../../scripts/actions'; 

export default class HeaderNav extends React.Component { 
    componentWillMount() { 
    const { dispatch } = this.props; 
    dispatch(navLoad()); 
    } 

    render() { 
    const { nav, isFetching } = this.props; 
    const navitems = nav.items.asMutable().map((item) => { 
     if(item.inNav === 'header') { 
     return <li key={item._id}><Link to={item.slug}>{item.name}</Link></li> 
     } 
    }); 
    return(
     <ul class="c-primary-nav"> 
     { navitems } 
     </ul> 
    ) 
    } 
} 

function select(state) { 
    const { nav } = state; 
    return { 
    nav 
    }; 
} 

export default connect(select)(HeaderNav); 

zweite Komponente

// socialLinks.jsx 
import React from 'react'; 
import { connect } from 'react-redux'; 
import { socialLinksLoad } from '../../../scripts/actions'; 

export default class SocialLinks extends React.Component { 
    componentWillMount() { 
    const { dispatch } = this.props; 
    dispatch(socialLinksLoad()); 
    } 

    render() { 
    const { socialLinks, isFetching } = this.props; 
    const faString = 'fa '; 
    console.log('socialLinks', socialLinks.items) 
    const slComponents = socialLinks && socialLinks.items ? socialLinks.items.asMutable().map((item) => { 
     return <li key={item._id}><a class={faString + item.class} title={item.title} href={item.link}>{item.label}</a></li> 
    }) : null; 
    if(isFetching) { 
     return(
     <section class="loader"> 
      <span>Content is loading...</span> 
     </section> 
    ) 
    } else { 
     return(
     <ul class="c-social-links"> 
      { slComponents } 
     </ul> 
    ) 
    } 
    } 
} 

function select(state) { 
    const { socialLinks } = state; 
    return { 
    socialLinks 
    }; 
} 

export default connect(select)(SocialLinks); 

Auch Minderer, falls enthalten, die auf die Ausgabe

// reducer.js 
export function socialLinks(state = socialLinksInitialState, action) { 
    switch (action.type) { 
    case GET_SOCIAL_LINKS : 
     return Immutable(state).merge({ 
     items: action.payload.socialLinks, 
     isFetching: false 
     }) 
    case REQUEST_SOCIAL_LINKS : 
     return Immutable(state).merge({ 
     isFetching: true 
     }) 
    default: 
     return state; 
    } 
} 

export function nav(state = navInitialState, action) { 
    switch (action.type) { 
    case GET_NAV : 
     return Immutable(state).merge({ 
     items: action.payload.nav, 
     isFetching: false 
     }) 
    case REQUEST_NAV : 
     return Immutable(state).merge({ 
     isFetching: true 
     }) 
    default: 
     return state; 
    } 
} 

const rootReducer = combineReducers({ 
    socialLinks, 
    nav, 
    routing: routerReducer 
}); 

export default rootReducer; 

Antwort

1

Die componentWill in engem Zusammenhang steht Die Mount() -Methode wird unmittelbar vor dem anfänglichen Rendern aufgerufen. Für dieses erste Rendering sind die Requisiten bereits gesetzt: nav ist ein leeres Objekt (oder undefiniert), deshalb erhalten Sie den Fehler.

Der Effekt des Versands von navLoad() wird beim nächsten Rendern nach der Änderung des redux-Zustands auftreten.

This react-redux issue kann Ihnen zusätzliche Informationen geben.

Wenn Sie einige Daten für Ihre Komponente mit den Methoden componentWillMount() oder componentDidMount() initialisieren, müssen Sie beim erstmaligen Rendern nur den anfänglichen "leeren" Status in Ihrer render() -Methodenimplementierung berücksichtigen .

Zum Beispiel in Ihrem Fall, das wäre einfach so etwas wie diese:

const navitems = nav && nav.items ? nav.items.asMutable().map((item) => { 
    if(item.inNav === 'header') { 
    return <li key={item._id}><Link to={item.slug}>{item.name}</Link></li> 
    } 
}) : null; 
+0

Also muß ich dann die Requisiten auf die Komponente aus der übergeordneten Komponente zu übergeben? Das scheint der Kern dieses Problems zu sein, aber ich könnte es falsch verstehen. –

+1

Nein, ich habe gerade meine Antwort bearbeitet, um Ihnen ein Standardmuster für diesen Fall zu geben. –

+0

Interessanterweise funktionierte das perfekt, bis ich den Prozess für eine andere Komponente wiederholte. Jetzt scheint nur die letzte auf der Seite aufgerufene Komponente zu funktionieren. Ich nehme an, dass die Requisiten oder der Zustand irgendwie überschrieben werden, aber ich bin mir nicht sicher, wo. Ich habe meine Antwort aktualisiert, um die zweite Komponente einzuschließen. Kannst du sehen, wo ich falsch liege? –

Verwandte Themen