現在、グローバルイベント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>
)
}
}
おかげ - それはエラーを取り除く持っているが、SETSTATEは、コンポーネント、これはあるかもしれない理由を任意のアイデアを再レンダリングしていないようです:
は何かなどをしてみてください? :) –
BasketContainerで、componentWillMount()は、this.props.itemsを使用して状態を設定しています。handleUpdate()で同じことをしています。だから、国家はそこで変化していない。 –
componentWillMountは、レンダリングメソッドが実行される前に呼び出されます。このフェーズで状態を設定しても、再レンダリングは実行されません。 handleUpdate()では、 'data'パラメータに従ってthis.state.itemsを操作し、それに応じて状態を設定する必要があります。 –