2015-11-26 28 views
6

Tôi đang gặp phải sự cố vòng lặp vô hạn và tôi không thể thấy những gì đang kích hoạt nó. Nó dường như xảy ra trong khi rendering các thành phần.Thành phần kết xuất vòng lặp vô tận trên ReactJs

tôi có ba thành phần, tổ chức như thế này:

TimelineComponent 
    |--PostComponent 
     |--UserPopover 

TimelineComponenet:

React.createClass({ 
    mixins: [ 
     Reflux.listenTo(TimelineStore, 'onChange'), 
    ], 
    getInitialState: function() { 
     return { 
      posts: [],   
     } 
    }, 
    componentWillMount: function(){ 
     Actions.getPostsTimeline(); 
    }, 
    render: function(){ 
     return (
      <div className="timeline">     
       {this.renderPosts()} 
      </div> 
     ); 
    }, 
    renderPosts: function(){ 
     return this.state.posts.map(function(post){  
      return (
       <PostComponenet key={post.id} post={post} /> 
      ); 
     }); 
    }, 
    onChange: function(event, posts) { 
     this.setState({posts: posts}); 
    } 
}); 

PostComponent:

React.createClass({ 
    ... 
    render: function() { 
     return (
      ... 
      <UserPopover userId= {this.props.post.user_id}/> 
      ...   
     ); 
    } 
}); 

UserPopover:

module.exports = React.createClass({ 
    mixins: [ 
     Reflux.listenTo(UsersStore, 'onChange'), 
    ], 
    getInitialState: function() { 
     return { 
     user: null 
     }; 
    }, 
    componentWillMount: function(){ 
     Actions.getUser(this.props.userId); 
    }, 
    render: function() { 
     return (this.state.user? this.renderContent() : null); 
    }, 
    renderContent: function(){ 
     console.log(i++);  
     return (
     <div>   
      <img src={this.state.user.thumbnail} /> 
      <span>{this.state.user.name}</span> 
      <span>{this.state.user.last_name}</span> 
      ... 
     </div> 
    ); 
    }, 
    onChange: function() { 
     this.setState({ 
     user: UsersStore.findUser(this.props.userId)  
     }); 
    } 
}); 

Cuối cùng, đó cũng là UsersStore **:

module.exports = Reflux.createStore({ 
    listenables: [Actions], 
    users: [], 
    getUser: function(userId){  
     return Api.get(url/userId) 
      .then(function(json){ 
       this.users.push(json); 
       this.triggerChange(); 
     }.bind(this)); 
    }, 
    findUser: function(userId) {    
     var user = _.findWhere(this.users, {'id': userId});  
     if(user){ 
      return user; 
     }else{ 
      this.getUser(userId); 
      return []; 
     } 
    }, 
    triggerChange: function() { 
     this.trigger('change', this.users); 
    } 
}); 

Tất cả mọi thứ hoạt động đúng trừ UserPopover thành phần.

Đối với mỗi Mã bưu điện hiển thị một UserPopOver tìm nạp dữ liệu trong chu kỳ willMount.

Có điều là, nếu bạn nhận thấy tôi có dòng mã này console.log(i++); trong thành phần UserPopover, mà increments hơn và hơn

... 
3820 
3821 
3822 
3823 
3824 
3825 
... 

Clearl một vòng lặp vô hạn, nhưng tôi thực sự không biết nơi nó đến từ. Nếu bất cứ ai có thể cho tôi một gợi ý tôi sẽ rất biết ơn.

PS: Tôi đã thử phương pháp này trong các UsersStore nhưng sau đó tất cả các PostComponent có "người sử dụng" tương tự:

... 
getUser: function(userId){  
    return Api.get(url/userId) 
     .then(function(json){ 
      this.user = json; 
      this.triggerChange(); 
    }.bind(this)); 
}, 
triggerChange: function() { 
    this.trigger('change', this.user); 
} 
... 

Và trong UserPopover

... 
onChange: function(event, user) { 
    this.setState({ 
     user: user  
    }); 
} 
... 
+1

Cảm ơn bạn rất nhiều @ForceMagic vì bài đánh giá của bạn, giờ đây nó khá rõ ràng! – Yonirt

+1

Tôi rất vui vì bạn thích nó! Tôi thực sự cố gắng giữ bản chất trong khi sắp xếp lại một số ý tưởng! :) – ForceMagic

Trả lời

2

Vì bài đăng của bạn được tải xuống không đồng bộ, tôi tin rằng khi thành phần UserPopover của bạn thực thi thành phầnWillMount, props.userId không xác định và sau đó bạn gọi UsersStore.findUser (this.props.userId), Trong UserStore, getUser được gọi vì không thể tìm thấy người dùng trong bộ nhớ cục bộ.

LƯU Ý rằng mỗi lần ajax của người dùng hoàn tất, nó sẽ kích hoạt.Vì vậy, thành phần UserPopover thực hiện chức năng onChange và gọi lại UsersStore.findUser. Đó là một vòng lặp vô tận.

Vui lòng thêm console.log (this.props.userId) vào thành phần của UserPopoverWillMount để tìm hiểu xem nó có giống như những gì tôi đã nói ở trên không. Tôi thực sự không chắc chắn 100%.

Đó là vấn đề mà tất cả cá thể UserPopover chia sẻ cùng một UserStore, tôi nghĩ chúng ta nên suy nghĩ lại cấu trúc của các thành phần và cửa hàng này. Nhưng tôi vẫn chưa nghĩ ra cách tốt nhất.

1

Bạn có thể làm như sau:

TimelineComponent 
    |--PostComponent 
    |--UserPopover 

UserPopover chỉ lắng nghe các thay đổi và tự cập nhật.

UserPopover lắng nghe thay đổi tại cửa hàng, lưu giữ dữ liệu của người dùng sẽ ở trong cửa sổ bật lên và trên bản cập nhật thay đổi. Bạn cũng có thể gửi tọa độ để hiển thị. Không cần tạo Popover cho mỗi bài đăng.

Các vấn đề liên quan