我有一个名为Home.js的父组件,它从API检索数据并将数据作为属性发送到它的子组件DishItem.js,显示菜单详细信息。我正在尝试渲染dish_name,数量(可以更改)和net_cost,我将所有这些存储在一个状态中,并通过componentWillMount()生命周期方法为初始渲染设置它们的状态。但它无法设置状态并返回undefined。
Home.js
import React, { Component } from 'react';
import DishItem from './DishItem';
import $ from 'jquery';
export default class Home extends Component {
constructor() {
super();
this.state = {
dish: ''
}
}
getDishes() {
$.ajax({
url: 'http://testbed2.riktamtech.com/foody_buddy/public/api/dishes/dish/31816',
dataType: 'json',
cache: false,
success: function(response) {
this.setState({dish: response.data});
}.bind(this),
error: function(xhr, status, err) {
console.log(err);
}
});
}
componentWillMount() {
this.getDishes();
}
componentDidMount() {
this.getDishes();
}
render() {
return (
<div className="Home">
<DishItem dish={this.state.dish}/>
</div>
);
}
}
DishItem.js
import React, { Component } from 'react';
import Quantity from './Quantity';
import { browserHistory } from 'react-router';
import './style.css';
export default class DishItem extends Component {
constructor(props) {
super(props);
this.state = {
quantity: 1,
delivery: '',
total_cost: '',
net_cost: null,
counter: 1
}
}
componentWillMount() {
console.log(this.props.dish.net_cost); //undefined instead of some value
this.setState({net_cost: this.props.dish.net_cost});
console.log(this.state.net_cost); // null
}
handleChangeInQuantity(value) {
var net_cost = 0;
var total_cost = 0;
total_cost = value * this.props.dish.cost;
net_cost = value * this.props.dish.net_cost;
this.setState({quantity: value, net_cost: net_cost, total_cost: total_cost});
}
saveAndContinue(e) {
e.preventDefault();
}
render() {
let address = <div>{this.props.dish.address}<br/>{this.props.dish.landmark}<br/>{this.props.dish.locality}</div>
return (
<div>
<h3>{this.props.dish.name}<small>{this.props.dish.description}</small></h3>
Total- {this.state.net_cost}
<Quantity change_in_quantity={this.handleChangeInQuantity.bind(this)} />
<button className="btn btn-default" onClick={this.saveAndContinue.bind(this)}>Next</button>
</div>
);
}
}
答案 0 :(得分:2)
componentWillMount()函数只触发一次,它不等待从服务器获取数据。您应该在DishItem组件中使用componentWillReceiveProps(),并使用从Home组件发送到它的数据设置新状态。这样,只要DishItem从Home组件接收到新的props,它就会相应地更新。
答案 1 :(得分:1)
您不应该使用React组件的componentWillMount
方法来执行异步数据提取。移除您对getDishes
方法的来电,并将其保留在componentDidMount
中。在您的Home组件的render
方法中,检查状态是否已经具有该状态的菜肴数据。如果没有,请不要渲染DishItem组件。您可以添加“请稍候,加载”等消息。
当页面加载时,React将使用“loading”消息呈现组件并开始异步加载碟形数据。当数据加载并设置状态时,React将使用DishItem组件再次呈现组件。
以下是您的主页组件的更新版本:
import React, { Component } from 'react';
import DishItem from './DishItem';
import $ from 'jquery';
export default class Home extends Component {
constructor() {
super();
this.state = {
dish: null
};
}
getDishes() {
$.ajax({
url: 'http://testbed2.riktamtech.com/foody_buddy/public/api/dishes/dish/31816',
dataType: 'json',
cache: false,
success: function (response) {
this.setState({ dish: response.data });
}.bind(this),
error(xhr, status, err) {
console.log(err);
}
});
}
componentDidMount() {
this.getDishes();
}
render() {
return (
<div className="Home">
{
this.state.dish === null ?
<div>Please wait, loading…</div> :
<DishItem dish={this.state.dish} />
}
</div>
);
}
}
答案 2 :(得分:1)
似乎我无法添加评论,所以我会发送这个,因为已经有很多答案。因为这个原因,请不要给我减一:)
即使它在componentDidMount中,一旦它获取数据,它将重新渲染DOM,使它看起来像是初始渲染。如果提取速度很慢,您会看到它空白片刻,然后呈现您需要的内容。
如果您确实需要在第一时间显示它,我建议您在重定向到此页面之前获取数据并将其保存在Flux存储区或Redux存储区中。例如,获取数据并在then()或回调函数内进行重定向。