2016-04-11 17 views
0

現在、グローバルイベントPub/Subシステムを介して通信している2つのreactJSコンポーネント(親/子ではない)を持つレールアプリがあります。this.setStateは再レンダリングビューではありませんReactJSとRuby on Rails

しかし、this.setState({ items: this.props.items })を実行すると、メッセージCannot read property 'items' of undefinedが表示されます。

このエラーが発生する理由については、どなたでも助けていただけると思います。

私が持っている基本的な設定は次のとおりです。

BasketContainer - バスケットイベントパブリッシャに

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 - - 削除する二つの事象

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に加入バスケット出版社から

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

答えて

1

私はparamは「この」

REMOVE_ITEMのための同じ
this.token = PubSub.subscribe('ADD_BASKET', this.handleUpdate.bind(this)) 

にバインドされる必要があるような問題は、次のコード行

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

あなたが渡している機能であると思いますアクション。次に良いことがあります:)

+0

おかげ - それはエラーを取り除く持っているが、SETSTATEは、コンポーネント、これはあるかもしれない理由を任意のアイデアを再レンダリングしていないようです:

は何かなどをしてみてください? :) –

+0

BasketContainerで、componentWillMount()は、this.props.itemsを使用して状態を設定しています。handleUpdate()で同じことをしています。だから、国家はそこで変化していない。 –

+0

componentWillMountは、レンダリングメソッドが実行される前に呼び出されます。このフェーズで状態を設定しても、再レンダリングは実行されません。 handleUpdate()では、 'data'パラメータに従ってthis.state.itemsを操作し、それに応じて状態を設定する必要があります。 –

0

itemsBasketContainerを親クラスから渡すことになっています。だからあなたはエラーを取得していますCannot read property 'items' of undefined.

更新:あなたがエラーを言及した行は、間違った参照thisのためになっている行です。あなたの助けのための

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

ご協力いただきありがとうございます。 BasketContainerには親クラスがありませんが、私はPub/Subイベントシステムを使用しています。下のRohitのコメントはエラーを取り除いていますが、今はsetStateが再レンダリングされていません。なぜこれが起こっているのでしょうか? –

関連する問題