2015-03-31 14 views
9

Więc mam ten składnikReact sędziowie nie są aktualizowane między renderowanie

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> 
    ) 
    } 
}) 

pierwsze lineitems czasowe są renderowane sędziowie działają jak oczekiwano. Ale jeśli dodaję lineitem do this.props.shoot, obiekt refs tego komponentu nie zmienia się.

Tak na przykład powiedzieć, że miał tablicę 3 lineitems

[i1,i2,i3] 

this.refs byłoby

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

i kiedy zaktualizować tablicę elementu zamówienia będzie

[i1,i2,i3,i4] 

this.refs się nie zmienia, nadal będzie to

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

dlaczego aktualizacja obiektu refs nie jest renderowana? Komponenty LineItemRow aktualizują się prawidłowo, więc wiem, że nie jest z tym źle. Wszelkie spostrzeżenia będą mile widziane!

____Edit____ (wymagane, aby dodać więcej kodu dla kontekstu)

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

Jak i kiedy uaktualnienia listy elementu zamówienia? Jaką funkcję przekazano do this.pros.onChange? Czy masz bardziej odpowiedni kod? – magnudae

+1

Używam strumienia, więc lista lineitem jest aktualizowana ze znacznika danych i jest przekazywana przez składnik macierzysty. Już sprawdziłem i wszystko działa poprawnie. Przekazana funkcja onChange zapisuje dane w zapleczu i aktualizuje sklep po zmianie lineitem. Funkcja onchange wywołuje metodę getAjaxData(). method Jest to najważniejsza część kodu, ale opublikuję inny kod. Wszystko inne działa tak, jak powinno. Jestem prawie pewien, że to jest reakcja.Ponieważ zaktualizowana lista składników {lineitems} jest poprawna, a nawet zawiera poprawne wartości. –

+1

Czytałem więcej informacji na temat dokumentacji na Facebooku. Stawałem się trochę niepewny, jeśli możliwe jest dynamiczne dodawanie kolejnych ref. Po wstępnym renderowaniu. Nie widzę żadnych błędów w twoim kodzie, więc to moja jedyna teoria atm. Szukaj dalej, może znajdziesz coś [tutaj] (https://facebook.github.io/react/docs/more-about-refs.html). (jeśli jeszcze nie próbowałeś) – magnudae

Odpowiedz

0

Usuń wszystkie pozycje literatury i iteracji do odczytywania danych.

Procedura obsługi zmiany, którą należy przejść do składnika LineItem, powinna zostać wywołana i przekazać tylko te dane, które uległy zmianie. (Pojedyncze dane LineItem)

Jest to następnie przetwarzane w komponencie z obsługą stanu (DocumentContent).

Utwórz akcję ShootActions.updateLineItem(), która aktualizuje odpowiedni element zamówienia w sklepie, który następnie emituje zmianę i wszystko jest ponownie renderowane.

+0

Myślę, że opakowanie jest nieco zbędne po tym faktycznie. – dannyshaw

4

w sekcji „Uwaga” w dokumentacji na temat literatury reagować https://facebook.github.io/react/docs/more-about-refs.html

„Never dostępu bibl wewnątrz tynku metodą dowolny komponent - albo podczas dowolnego komponentu renderowanie metoda jest jeszcze uruchomiony w dowolnym miejscu na wezwanie stosie . "

To jest dokładnie to, co robisz.

Zamiast tego należy przechowywać stanu o składnik this.state lub właściwości składnika this.props