Ich habe eine Rails-App mit zwei reactJS-Komponenten (nicht Eltern/Kind), die derzeit über eine globale Ereignisse Pub/Sub-System kommunizieren.this.setState re-rendering nicht anzeigen ReactJS und Ruby on Rails
Wenn ich jedoch this.setState({ items: this.props.items })
ausführen bekomme ich die Nachricht Cannot read property 'items' of undefined
.
Jede Hilfe, die Leute anbieten können, warum ich diesen Fehler bekommen könnte, würde sehr geschätzt werden.
Das Basis-Setup ich habe, ist:
BasketContainer - abonniert zwei Ereignisse
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 - In den Warenkorb Event Publisher
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 - entfernen von Basket Publisher
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>
)
}
}
Danke für Ihre Hilfe - das ist die Beseitigung der Fehler bekommt aber setState scheint nicht die Component-Rendering wieder werden, eine Idee woran das liegen könnte? :) –
In BasketContainer, componentWillMount() setzen Sie den Status mit this.props.items, in handleUpdate() machen Sie dasselbe. Also ändert sich der Staat dort nicht. –
componentWillMount wird aufgerufen, bevor die Rendermethode ausgeführt wird. Es ist wichtig zu beachten, dass das Setzen des Status in dieser Phase kein erneutes Rendering auslöst. In handleUpdate() müssen Sie this.state.items gemäß dem Parameter 'data' bearbeiten und dann den Status entsprechend festlegen. –