Ad

Reactjs Mounting State Before Initial Render Or Keep As Is?

- 1 answer

State on the initial render here is the initial state. Am using componentWillMount() however it won't work without first checking whether the component is mounted. The result when using rawMarkup() is an empty initial state object. Everything functions properly on the re-render but wondering why the post object within state is still empty on the initial render. Is there a better way of accomplishing this? Thank you.

var Post = React.createClass({
propTypes: {
    source: React.PropTypes.string.isRequired,
},

getInitialState: function() {
    return {
        post: {}
    };
},

getDefaultProps: function() {
    return {
        source: 'http://localhost:3000/api/posts/' + postSlug
    };
},

componentWillMount: function() {
    $.get(this.props.source, function(result) {
        if (this.isMounted()) {
            this.setState({post: result});
        }
    }.bind(this));
},

rawMarkup: function() {
    console.log(this.state.post);
    var rawMarkup = marked(this.state.post.body || '', {sanitize: true});
    return { __html: rawMarkup };
 },

render: function() {
    var post = this.state.post;
    var date = moment(post.date).format('MM[/]DD[/]YYYY');
    return (
        React.createElement('div', {style: {marginLeft: '115px'}},
            React.createElement('h1', {style: {marginTop: '50px'}}, post.title),
            React.createElement('h5', {style: {marginBottom: '25px'}}, date),
            React.createElement('span', {dangerouslySetInnerHTML: this.rawMarkup()})
        )
    );
}

});

Ad

Answer

By default, the jQuery get request is asynchronous, so the initial render happens before the request completes and this.setState({post: result}) is called. You could make the get request synchronous (How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?), or figure out a way to gracefully deal with no data on the initial render (recommended).

Ad
source: stackoverflow.com
Ad