Props not setting state

- 1 answer

Ad

I have a react component that gets a prop from another parent component. I checked in react developer tools, and the prop is for sure getting passed.

Here is my code:

var Post = React.createClass({
  getInitialState: function () {
    return { content: this.props.content };
  },
  rawMarkup: function() {
    var rawMarkup = marked(this.state.content, {sanitize: true});
    return { __html: rawMarkup };
  },
  render: function() {
    return (
       <div>
          {this.props.content }
          <div dangerouslySetInnerHTML={ this.rawMarkup() } />
       </div>
    );
  }
});

This results in the error: Uncaught TypeError: Cannot read property 'replace' of undefined for marked.js. However, when I setInitialState to return { content: "Blah" }; it works fine. So it looks like the prop is not set there?

But when I do the {this.props.content} in the render, it works fine?

Ad

Answer

Ad

It's just that your state is out of date. Try adding this:

getInitialState: function () {
  return { content: this.props.content || '' };
},
componentWillReceiveProps: function(nextProps) {
  if (this.props.content !== nextProps.content) {
    this.setState({
      content: nextProps.content || '',
    });
  }
},

Read more about components' lifecycle here.

Edit: This will solve your problem, but generally using state this way is an anti-pattern (unless content is an input or something, you haven't mentioned that in your question). What you should do instead is create a new component that will only accept content prop and render marked output. I suggest you use a stateless functional component here.

var MarkedContent = (props) => {
  return <div dangerouslySetInnerHTML={{__html: marked(props.content || '', {sanitize: true})}}></div>
}

Drop this component inside your Post component like this:

var Post = React.createClass({
  render: function() {
    return (
       <div>
          <MarkedContent content={this.props.content} />
       </div>
    );
  }
});

Thanks David Walsh!

Ad
source: stackoverflow.com
Ad