2016-04-11 20 views
0

Şu anda global etkinlikler Pub/Sub sistemi üzerinden iletişim kurmakta olan iki reakJS bileşeni (ana/çocuk değil) içeren bir raylı uygulamasına sahibim.this.setState yeniden oluşturulmuyor görünümü ReactJS ve Ruby on Rails

Ancak, this.setState({ items: this.props.items }) çalıştırdığımda Cannot read property 'items' of undefined iletisini alıyorum.

İnsanların, bu hatayı alabilmem için neden olabilecekleri herhangi bir yardım çok takdir edilecektir.

Ben basit bir kurumdur:

BasketContainer - iki olay

class BasketContainer extends React.Component{ 

constructor() { 
    super() 
    this.state = { 
     items: [], 
     subTotal: 0, 
     totalPrice: 0, 
     deliveryPrice: 0 
    } 
} 
componentWillMount() { 
    this.setState({ 
     items: this.props.items, 
    }) 
} 
componentDidMount() { 
    this.token = PubSub.subscribe('ADD_BASKET', this.handleUpdate) 
    this.token = PubSub.subscribe('REMOVE_ITEM', this.handleUpdate) 
    this.calculateTotals(); 
} 

componentWillUnmount() { 
PubSub.unsubscribe(this.token) 
} 

handleUpdate(msg, data){ 
    console.log(msg) 
    this.setState({ 
     items:this.props.items // ERROR MESSAGE - Cannot read property 'items' of undefined 
    }) 
} 
.... Rest of file 

ProductItem abone - Basket Olay Yayıncısı'na

class ProductItem extends React.Component{ 

constructor() { 
    super() 

    this.state = { 
     name: '', 
     price: 0, 
     code: '', 
     id: '' 
    } 
} 

componentWillMount() { 
    this.setState({ 
     name: this.props.data.name, 
     price: this.props.data.price, 
     code: this.props.data.code, 
     id: this.props.data.id 
    }) 
} 

addtoBasket() { 
    $.ajax({ 
     type: "POST", 
     url: "/items", 
     dataType: "json", 
     data: { 
      item: { 
       name: this.state.name, 
       price: this.state.price, 
       code: this.state.code 
      } 
     }, 
     success: function(data) { 
      PubSub.publish('ADD_BASKET', data); // THIS WORKS FINE 
      console.log("success"); 
     }, 
     error: function() { 
      console.log("error"); 
     } 
    }) 
} 

render(){ 
    let productName = this.props.data.name 
    let productPrice = this.props.data.price 
    let productCode = this.props.data.code 
    let productImg = this.props.data.image_url 

    return (
     <div className="col-xs-12 col-sm-4 product"> 
      <img src={productImg}/> 
      <h3 className="text-center">{productName}</h3> 
      <h5 className="text-center">£{productPrice}</h5> 
      <div className="text-center"> 
       <button onClick={this.addtoBasket.bind(this)} className="btn btn-primary">Add to Basket</button> 
      </div> 
     </div> 
    ) 
} 
} 

BasketItem ekle - Kaldır Basket Publisher'dan

class BasketItem extends React.Component{ 

constructor(props) { 
    super() 

    this.state = { 
     name: '', 
     price: 0, 
     code: '', 
     id: '', 
     quantity: 1, 
    } 
} 

componentWillMount() { 
    this.setState({ 
     name: this.props.data.name, 
     price: this.props.data.price, 
     code: this.props.data.code, 
     id: this.props.data.id, 
    }) 
} 

deleteItem() { 
    let finalUrl = '/items/' + this.state.id; 
    $.ajax({ 
     type: "DELETE", 
     url: finalUrl, 
     dataType: "json", 
     success: function(data) { 
      PubSub.publish('REMOVE_ITEM', data); // THIS WORKS FINE 
     }, 
     error: function() { 
      console.log("error"); 
     } 
    }) 
} 

render(){ 
    let itemName = this.props.data.name 
    let itemCode = this.props.data.code 
    let itemQuantity = 1 
    let itemPrice = (this.props.data.price * itemQuantity).toFixed(2) 
    const itemId = this.props.data.id 

    return(
     <tr> 
      <td>{itemName}</td> 
      <td>{itemCode}</td> 
      <td>{itemQuantity}</td> 
      <td><button className="btn btn-warning" onClick={this.deleteItem.bind(this)}>Remove</button></td> 
      <td>£{itemPrice}</td> 
     </tr> 
    ) 
} 
} 

cevap

1

Ben sorunun kodda Eğer param olarak geçiyoruz fonksiyon REMOVE_ITEM için 'bu'

this.token = PubSub.subscribe('ADD_BASKET', this.handleUpdate.bind(this)) 

aynı ile binded gereken

this.token = PubSub.subscribe('ADD_BASKET', this.handleUpdate) 

aşağıdaki satırla olduğunu düşünüyorum aksiyon. Öyleyse gitmek için iyi olmalı :)

+0

teşekkür - re-render edilecek Bileşen o hata kurtulmak var ama setState görünmüyor, bir fikrin bu olabilir neden? :) –

+0

BasketContainer'da, componentWillMount() öğesi, this.props.items ile durumu ayarlıyorsunuz, handleUpdate() içinde aynı şeyi yapıyorsunuz. Yani, devlet orada değişmiyor. İşleme yöntemi yürütülmeden önce –

+0

componentWillMount çağrılır. Durumun bu aşamada ayarlanmasının yeniden oluşturulmasını tetiklemeyeceğini belirtmek önemlidir. HandleUpdate() 'de, this.state.items' data 'parametresine göre işlem yapmalı ve durumu buna göre ayarlamanız gerekir. –

0

Üst sınıfından items ürününü BasketContainer'a iletmeniz gerekiyor. Bu nedenle, hata alıyorsunuz Cannot read property 'items' of undefined.

Güncelleştirme: Hatandan bahsettiğiniz satır, yanlışlık this;

gibi bir şey deneyin: Yardımlarınız için

handleUpdate(msg, data){ 
    var self = this; 
    this.setState({ 
     items: self.props.items // Here get props from self variable 
    }) 
} 
+0

Yardımlarınız için teşekkürler. BasketContainer'ın bir ana sınıfı yok, bu yüzden Pub/Sub olay sistemini kullanıyorum.Rohit'in yorumu aşağıdaki hatadan kurtuldu ancak şimdi setState yeniden oluşturulmuyor. Bunun neden olabileceği hakkında bir fikrin var mı? –