最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using PropTypes when immutable-js in react-js - Stack Overflow

programmeradmin1浏览0评论

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.statements.constructor);
    return (
      <div className='commentBox container'>
        <h1>Comments</h1>
        <CommentForm url={this.props.url} />
        <CommentList comments={this.statements} />
      </div>
    );
}


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

// CommentStore.js
handleAddComment(comment) {
    thisments.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 .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.

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.

Share Improve this question edited Nov 22, 2016 at 19:35 Naftali 146k41 gold badges247 silver badges304 bronze badges asked Aug 23, 2015 at 10:02 rubyu2rubyu2 2701 gold badge3 silver badges14 bronze badges 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) – zerkms Commented Aug 23, 2015 at 10:10
  • I learned this way from facebook.github.io/react/docs/…. – rubyu2 Commented Aug 23, 2015 at 10:30
  • In that very article they assign the result of the call to the property itself. – zerkms 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. – zerkms Commented Aug 23, 2015 at 10:56
  • Thank you.I think I misunderstood the immutable. – rubyu2 Commented Aug 23, 2015 at 11:05
 |  Show 4 more comments

2 Answers 2

Reset to default 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

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>

发布评论

评论列表(0)

  1. 暂无评论