javascript - Render 'async' function return value in render method (React)
问题描述
I'm trying to render a simple return value from an async
function in my react app however every time I try to my entire app will not render at all. Without calling the function my app renders fine. Also if I console.log my return value (result) in my function it returns the correct value on the console but nothing in the app renders. Any ideas what's going on?
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>
);
}
}
推荐阅读
- reactjs - 我如何在 Heroku 上部署 React 项目
- c - 如何在 C 语言的 macOs 上的 Visual Studio Code 中开始调试?
- python - Amazon AWS Kinesis Video Boto GetMedia/PutMedia
- matlab - LSB 加解密
- powershell - 如何在 PowerShell 中打开新控制台,然后在其中执行某些操作?
- javascript - 反应路由器 dom 不呈现条件路由(登录和身份验证)
- python - 函数中返回和打印的区别
- sql - 未捕获的异常导致崩溃后的 SQLite 日志文件行为
- visual-studio-code - 在 Visual Studio Code 中找不到 Auto Fix On Save 按钮
- mysql - 如何组合列以创建主键以添加 2 个表