14

I am using immutable-js and react-immutable-proptypes in React.

// CommentBox.jsx
getInitialState() {
    return {
        comments: Immutable.List.of(
            {author: 'Pete Hunt', text: 'Hey there!'},
            {author: 'Justin Gordon', text: 'Aloha from @railsonmaui'}
        )
    };
},
render(){
    console.log(this.state.comments.constructor);
    return (
      <div className='commentBox container'>
        <h1>Comments</h1>
        <CommentForm url={this.props.url} />
        <CommentList comments={this.state.comments} />
      </div>
    );
}


// CommentList.jsx
propTypes: {
    comments: React.PropTypes.instanceOf(Immutable.List),
},

// CommentStore.js
handleAddComment(comment) {
    this.comments.push(comment);
}

When the page initialization, it's no problem,all is ok,no warning. The console log shows the comments is function List(value). When I add a new comment, it looks work well,but there is a warning

Warning: Failed propType: Invalid prop comments supplied to CommentList, expected instance of List. Check the render method of CommentBox.

and the console log shows that the comments is function Array(). So, why does the comments constructor change from List to Array?

And and I have read http://facebook.github.io/react/docs/advanced-performance.html#immutable-js-and-flux.

The messages store could keep track of the users and messages using two lists:

this.users = Immutable.List();
this.messages = Immutable.List();

It should be pretty straightforward to implement functions to process each payload type. For instance, when the store sees a payload representing a new message, we can just create a new record and append it to the messages list:

this.messages = this.messages.push(new Message({
  timestamp: payload.timestamp,
  sender: payload.sender,
  text: payload.text
});

Note that since the data structures are immutable, we need to assign the result of the push function to this.messages.

9
  • 1
    this.comments.push(comment) expression returns a new list but does not modify the list in place (by definition, since it's immutable) Commented Aug 23, 2015 at 10:10
  • I learned this way from facebook.github.io/react/docs/…. Commented Aug 23, 2015 at 10:30
  • In that very article they assign the result of the call to the property itself. Commented Aug 23, 2015 at 10:31
  • "Note that since the data structures are immutable, we need to assign the result of the push function to this.messages." Please go through that article one more time. Commented Aug 23, 2015 at 10:56
  • Thank you.I think I misunderstood the immutable. Commented Aug 23, 2015 at 11:05

2 Answers 2

17

I came here looking to find a solution that would allow either an array or any sort of iterable object from ImmutableJS to be passed as the prop. In case anyone else finds this useful, here's what I came up with:

PropTypes.oneOfType([
  PropTypes.instanceOf(Array),
  PropTypes.instanceOf(Immutable.Iterable)
]).isRequired
Sign up to request clarification or add additional context in comments.

Comments

0

You can specify a custom validator.

propName: function(props, propName, componentName) {
  if (!List.isList(props[propName]) && !Array.isArray(props[propName])) {
    return new Error(
      'Invalid prop `' + propName + '` supplied to' +
      ' `' + componentName + '`. Validation failed.'
    );
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.min.js"></script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.