2015-03-31 37 views
9

Vì vậy, tôi có thành phần nàyPhản ứng refs không cập nhật giữa làm

var LineItemRowsWrapper = React.createClass({ 
    current_lineitem_count: 0, 

    getAjaxData: function(){ 
    var lineitem_data = []; 
    for(var i = 0; i < this.current_lineitem_count; i++){ 
     var data = this.refs['lineitem_'+i].getAjaxData(); 

     lineitem_data.push(data) 
    } 
    return lineitem_data; 
    }, 

    getLineitems: function(){ 
    var self = this; 

    var lineitem_components = []; 
    this.current_lineitem_count = 0; 
    if(this.props.shoot){ 
     var preview = this.props.preview; 

     var lineitems = this.props.shoot.get_lineitems(); 


     lineitem_components = lineitems.map(function (item, index) { 
      var ref_str = 'lineitem_'+self.current_lineitem_count; 
      self.current_lineitem_count++; 

      return (
      <LineItemRow item={item} key={index} ref={ref_str} preview={preview} onChange={self.props.onChange} /> 
     ) 
     }); 
     } 

    return lineitem_components; 
    }, 

    render: function() { 
    var lineitems = this.getLineitems(); 
    return (
     <div> 
     {lineitems} 
     </div> 
    ) 
    } 
}) 

các Chi tiết đơn hàng lần đầu tiên được trả lại các refs làm việc như mong đợi. Nhưng nếu tôi thêm một lineitem vào this.props.shoot đối tượng refs của thành phần này không thay đổi.

Vì vậy, ví dụ như nói rằng tôi đã có một mảng của 3 Chi tiết đơn hàng

[i1,i2,i3] 

this.refs sẽ

{lineitem_0:{}, lineitem_1:{}, lineitem_2:{}} 

và khi tôi cập nhật mảng chi tiết đơn hàng của tôi để được

[i1,i2,i3,i4] 

this.refs không thay đổi, nó vẫn sẽ là

{lineitem_0:{}, lineitem_1:{}, lineitem_2:{}} 

tại sao đối tượng refs không cập nhật giữa kết xuất? Các thành phần LineItemRow cập nhật đúng để tôi biết nó không phải là một cái gì đó sai trên mặt trận đó. Bất kỳ thông tin chi tiết nào cũng sẽ được đánh giá cao!

____Edit____ (yêu cầu thêm mã hơn cho bối cảnh)

var DocumentContent = React.createClass({ 
    contextTypes: { 
    router: React.PropTypes.func.isRequired 
    }, 

    getParams: function(){ 
    return this.context.router.getCurrentParams() 
    }, 

    getInitialState: function() { 
    return { 
     shoot: ShootStore.get_shoot(this.getParams().shoot_id), 
    } 
    }, 

    componentWillMount: function() { 
    ShootStore.bind('change', this.onStoreUpdate); 
    }, 

    componentWillUnmount: function() { 
    ShootStore.unbind('change', this.onStoreUpdate); 
    }, 

    onStoreUpdate: function(){ 
    this.setState(this.getInitialState()); 
    }, 



    addLineItem: function() { 
     ShootActions.create_lineitem(this.state.shoot.id); 
    }, 


    update_shoot_timeout: null, 

    update_shoot:function(){ 
    var self = this; 
    window.clearTimeout(this.update_shoot_timeout) 
    this.update_shoot_timeout = window.setTimeout(function(){ 

     var lineitem_data = self.refs.lineitems.getAjaxData() 

     if(self.props.shoot){ 
      ShootActions.update_shoot(self.state.shoot.id, lineitem_data) 
     } 
    }, 500) 
    }, 


    render: function() { 

    var shoot = this.state.shoot; 
    return (
     <div className='document__content'> 
      <div className='row'> 


      <div className='document__expenses'> 
       <h3 className='lineitem__title'> Expenses </h3> 
       <LineItemRowsWrapper shoot={shoot} onChange={this.update_shoot} ref='lineitems'/> 

      </div> 
      <button onClick={this.addLineItem} className="btn-small btn-positive"> 
         + Add Expense 
        </button> 




     </div> 
    ); 
    } 
}) 
+1

Làm thế nào và khi nào bạn cập nhật danh sách chi tiết đơn hàng? Loại hàm nào được chuyển vào this.pros.onChange? Bạn có mã có liên quan hơn không? – magnudae

+1

Tôi đang sử dụng thông lượng và do đó danh sách lineitem được cập nhật từ một data_store và được thông qua trong thành phần cha. Tôi đã kiểm tra và điều này là tất cả hoạt động chính xác. Hàm onChange được truyền trong lưu dữ liệu vào backend và cập nhật cửa hàng khi một lineitem thay đổi. Hàm onchange gọi hàm getAjaxData(). Phương pháp Đây là phần có liên quan nhất của mã, nhưng tôi sẽ đăng mã khác của tôi. Mọi thứ khác đang làm việc như nó cần. Tôi khá chắc chắn đây là một điều phản ứng.Bởi vì danh sách thành phần {lineitems} đang được cập nhật là chính xác và thậm chí có các tham chiếu chính xác. –

+1

Tôi đọc thêm một số thông tin về tài liệu về tài liệu trên facebook. Tôi đã trở thành một chút không chắc chắn nếu nó có thể tự động thêm refs nhiều hơn sau khi render ban đầu. Tôi không thể nhìn thấy bất kỳ lỗi trong mã của bạn vì vậy đây là lý thuyết duy nhất của tôi atm. Tiếp tục tìm kiếm, có thể bạn có thể tìm thấy một cái gì đó [ở đây] (https://facebook.github.io/react/docs/more-about-refs.html). (nếu bạn chưa thử) – magnudae

Trả lời

0

Hủy bỏ tất cả các refs và lặp đi lặp lại của bạn để đọc dữ liệu.

Trình xử lý onchange mà bạn vượt qua tất cả các con đường xuống thành phần LineItem sẽ được gọi và chỉ truyền dữ liệu thay đổi. (Dữ liệu LineItem đơn)

Điều này sau đó được xử lý lại tại thành phần có xử lý trạng thái (DocumentContent).

Tạo một hành động ShootActions.updateLineItem() cập nhật chi tiết đơn hàng có liên quan trong cửa hàng, sau đó phát ra thay đổi và mọi thứ sẽ hiển thị lại.

+0

Tôi nghĩ rằng các wrapper là một chút dư thừa sau này thực sự. – dannyshaw

4

Trong phần "Thận trọng" trong phản ứng tài liệu về refs https://facebook.github.io/react/docs/more-about-refs.html

"truy cập refs Chưa bao giờ bên trong làm cho phương pháp của bất kỳ thành phần - hoặc trong khi bất kỳ của Phương thức render thậm chí đang chạy bất cứ nơi nào trong cuộc gọi chồng thành phần . "

Đó chính xác là những gì bạn đang làm.

Thay vào đó bạn nên lưu trữ nhà nước về các thành phần trong this.state hoặc tài sản của các thành phần trong this.props

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