在渲染方法中渲染 'async' 函数 return 值 (React)
Render 'async' function return value in render method (React)
我正在尝试从我的 React 应用程序中的 async
函数渲染一个简单的 return 值,但是每次我尝试渲染时我的整个应用程序都不会渲染。无需调用该函数,我的应用程序即可正常呈现。此外,如果我在我的函数中 console.log 我的 return 值(结果)它 return 是控制台上的正确值,但应用程序中没有任何内容呈现。有什么想法吗?
class TitleCards extends Component {
constructor(props){
super(props)
this.totalPortfolio = this.totalPortfolio.bind(this);
this.getIntradayPrice = this.getIntradayPrice.bind(this);
}
async getIntradayPrice(tick) {
const resp = await fetch(`${IEX.base_url}/stock/${tick}/intraday-prices?chartLast=1&token=${IEX.api_token}`);
return resp.json();
}
async totalPortfolio() {
const respPromises = this.props.info.map(({ tick }) => this.getIntradayPrice(tick));
const respArrays = await Promise.all(respPromises);
console.log(respArrays);
const result = respArrays.reduce((acc, val, index) => acc + val[0].close * this.props.info[index].amtPurch, 0)
console.log(result);
return result;
}
render(){
return(
<div className="positioning">
<div className="StockCardTitle">
<img src={Folder} className="StockCardTitle-image" />
{this.totalPortfolio()}
</div>
</div>
)
}
}
export default TitleCards;
问题
React 组件和生命周期是 100% 同步的,尤其是 render
方法。 render
方法也被认为是一个纯函数,这意味着它应该具有零副作用(比如获取数据!!)。
解决方案
您应该重构代码以在 componentDidMount
和 componentDidUpdate
之一或两者中获取数据,并将结果保存到本地组件状态以进行渲染。
这是一个重构示例。
class TitleCards extends Component {
constructor(props){
super(props);
state = {
portfolioTotal: '',
};
this.totalPortfolio = this.totalPortfolio.bind(this);
this.getIntradayPrice = this.getIntradayPrice.bind(this);
}
async getIntradayPrice(tick) {
const resp = await fetch(`${IEX.base_url}/stock/${tick}/intraday-prices?chartLast=1&token=${IEX.api_token}`);
return resp.json();
}
async totalPortfolio() {
const { info } = this.props;
const respPromises = info.map(({ tick }) => this.getIntradayPrice(tick));
const respArrays = await Promise.all(respPromises);
const result = respArrays.reduce((acc, val, index) => acc + val[0].close * info[index].amtPurch, 0)
return result;
}
// When the component mounts, call totalPortfolio
componentDidMount() {
this.totalPortfolio()
.then(portfolioTotal => {
this.setState({
portfolioTotal
});
})
.catch(error => {
// add any required error handling/messaging here
});
}
render() {
const { portfolioTotal } = this.state;
return(
return(
<div className="positioning">
<div className="StockCardTitle">
<img src={Folder} className="StockCardTitle-image" />
{portfolioTotal} // <-- render state value
</div>
</div>
);
}
}
我正在尝试从我的 React 应用程序中的 async
函数渲染一个简单的 return 值,但是每次我尝试渲染时我的整个应用程序都不会渲染。无需调用该函数,我的应用程序即可正常呈现。此外,如果我在我的函数中 console.log 我的 return 值(结果)它 return 是控制台上的正确值,但应用程序中没有任何内容呈现。有什么想法吗?
class TitleCards extends Component {
constructor(props){
super(props)
this.totalPortfolio = this.totalPortfolio.bind(this);
this.getIntradayPrice = this.getIntradayPrice.bind(this);
}
async getIntradayPrice(tick) {
const resp = await fetch(`${IEX.base_url}/stock/${tick}/intraday-prices?chartLast=1&token=${IEX.api_token}`);
return resp.json();
}
async totalPortfolio() {
const respPromises = this.props.info.map(({ tick }) => this.getIntradayPrice(tick));
const respArrays = await Promise.all(respPromises);
console.log(respArrays);
const result = respArrays.reduce((acc, val, index) => acc + val[0].close * this.props.info[index].amtPurch, 0)
console.log(result);
return result;
}
render(){
return(
<div className="positioning">
<div className="StockCardTitle">
<img src={Folder} className="StockCardTitle-image" />
{this.totalPortfolio()}
</div>
</div>
)
}
}
export default TitleCards;
问题
React 组件和生命周期是 100% 同步的,尤其是 render
方法。 render
方法也被认为是一个纯函数,这意味着它应该具有零副作用(比如获取数据!!)。
解决方案
您应该重构代码以在 componentDidMount
和 componentDidUpdate
之一或两者中获取数据,并将结果保存到本地组件状态以进行渲染。
这是一个重构示例。
class TitleCards extends Component {
constructor(props){
super(props);
state = {
portfolioTotal: '',
};
this.totalPortfolio = this.totalPortfolio.bind(this);
this.getIntradayPrice = this.getIntradayPrice.bind(this);
}
async getIntradayPrice(tick) {
const resp = await fetch(`${IEX.base_url}/stock/${tick}/intraday-prices?chartLast=1&token=${IEX.api_token}`);
return resp.json();
}
async totalPortfolio() {
const { info } = this.props;
const respPromises = info.map(({ tick }) => this.getIntradayPrice(tick));
const respArrays = await Promise.all(respPromises);
const result = respArrays.reduce((acc, val, index) => acc + val[0].close * info[index].amtPurch, 0)
return result;
}
// When the component mounts, call totalPortfolio
componentDidMount() {
this.totalPortfolio()
.then(portfolioTotal => {
this.setState({
portfolioTotal
});
})
.catch(error => {
// add any required error handling/messaging here
});
}
render() {
const { portfolioTotal } = this.state;
return(
return(
<div className="positioning">
<div className="StockCardTitle">
<img src={Folder} className="StockCardTitle-image" />
{portfolioTotal} // <-- render state value
</div>
</div>
);
}
}