2017-10-16 3 views
0

Ich habe ein Problem mit einer Komponente, die einige erforderliche propTypes enthält.Aktualisierungsstatus vor dem Rendern: propType als erforderlich markiert, aber undefiniert

Der Fehler Ich erhalte ist:

Warning: Failed prop type: The prop `firstname` is marked as required in `UserHeader`, but its value is `undefined`. 
in UserHeader (at App.js:32) 
in App (created by Connect(App)) 
in Connect(App) (at index.js:17) 
in Provider (at index.js:16) 

Und mein Code ...

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 

import ErrorBoundary from './containers/ErrorBoundary' 
import UserHeader from './components/UserHeader'; 
import Header from './components/Header'; 

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

    componentWillMount() { 
    // Pretend this is an API call that takes a second 
    setTimeout(() => { 
     const data = { 
     user: { 
      firstname: 'bughunter', 
      level: 55 
     } 
     }; 
     this.props.didMountHandler(data) 
    }, 1000); 
    } 

    render() { 
    return (
     <ErrorBoundary> 
     <Header /> 
     <UserHeader 
      firstname={this.props.firstname} 
      level={this.props.level} 
     /> 
     </ErrorBoundary> 
    ); 
    } 
} 

const mapStateToProps = (state, ownProps) => { 
    return { 
    firstname: state.user.firstname, 
    level: state.user.level 
    } 
}; 

const mapDispatchToProps = dispatch => ({ 
    didMountHandler: data => { 
    dispatch({ 
     type: 'USER_DATA_RECEIVED', 
     data 
    }); 
    } 
}) 

const AppContainer = connect( 
    mapStateToProps, 
    mapDispatchToProps 
)(App); 

export default AppContainer; 

ich den Zustand vor dem render Verfahren modifiziert ich genannt hat, so bin verwirrt, wie Requisiten für UserHeader werden überprüft, bevor die setTimeout fertig ist?

Wie kann ich Rendering/propChecking aussetzen, bis setTimeout abgeschlossen ist?

Ich dachte über einigen anfänglichen Standardzustand eingestellt wird, wenn das Geschäft zu schaffen, etwa so:

{ 
    user: { 
     firstname: '', 
     level: 0 
    } 
} 

... aber das scheint ein wenig hackish.

+0

Mai werden Sie diese zur Kasse wollen https://stackoverflow.com/questions/43312223/asynchronous-call-in-componentwillmount-finishes-after-render-method – praveenweb

Antwort

3

Sie ändern den Status NICHT vor render, da Sie ein setTimeout verwenden. Render wartet nicht auf Ihre setTimeout und wird direkt nach componentWillMount aufgerufen.

Sie müssen einige Standardwerte im Redux Reducer einstellen. Sie können in der Minderer

user: null, 
.... 

und beim Rendern Scheck nur einstellen, wenn Sie den Benutzer haben oder nicht

render() { 
    const { user } = this.props; 
    { user && <UserHeader firstname={user.firstname} level={user.level} /> } 

Und in mapStateToProps kopieren Sie einfach den gesamten user obj:

const mapStateToProps = (state, ownProps) => { 
    return { 
    user: state.user 
    } 
}; 

Es gibt auch andere Möglichkeiten, es zu tun. Sie könnten einfach die Standardwerte für firstName und level im Reducer wie vorgeschlagen einstellen, oder Sie könnten die UserHeader immer mit einer user Requisite rendern und darin entscheiden, was angezeigt werden soll, wenn Sie die Werte subValues ​​nicht gesetzt haben.

0

Fügen Sie eine Ladekomponente oder null wie unten hinzu. Und den lokalen Status verwenden.

state = { initialized: false } 

componentWillMount() { 
// Pretend this is an API call that takes a second 
setTimeout(() => { 
    const data = { 
    user: { 
     firstname: 'bughunter', 
     level: 55 
    } 
    }; 
    this.props.didMountHandler(data) 
    this.setState({ initialized: true }); 
}, 1000); 
} 

render(){ 
    if(!this.state.initialized){ 
     return null; 
    } 

    return (
    <ErrorBoundary> 
     <Header /> 
     <UserHeader 
      firstname={this.props.firstname} 
      level={this.props.level} 
     /> 
    </ErrorBoundary> 
    ); 
} 
Verwandte Themen