好吧,让我开始吧,这段代码可能看起来很乱,但我认为问题很简单。
因此,每当我更改以下“TitleCards”子组件的父级中的状态时,子组件中的状态也会发生变化,但“TitleCards”组件的渲染方法中的组合总价值不会根据更改重新计算状态。我认为这与 async 函数有关,但我不确定。
有什么想法吗?我想要的只是当子组件中的状态发生变化时(我可以使用开发工具看到它正在发生变化),让组件自动重新渲染/重新计算带有更改状态的组合总和。
import "./StockCard.css";
import { IEX } from "./IEX.js";
import moment from 'moment';
import Folder from "./folder.png";
import MoneyBag from "./money-bag.png";
import Handshake from "./hand-shake.png";
import add from "./add.png";
import NumberFormat from 'react-number-format';
const LOGO_API = "https://eodhistoricaldata.com/img/logos/US/";
class TitleCards extends Component {
constructor(props){
super(props)
this.arr = this.totalPortfolio();
this.state ={
portfolioTotal: '',
WhenThisChangesShouldntTheComponentReRender: this.props.info,
}
this.totalPortfolio = this.totalPortfolio.bind(this);
this.getIntradayPrice = this.getIntradayPrice.bind(this);
}
static defaultProps = {
TitleCardInfo: [
{ name: "Portfolio", ticker: "DIA"},
{ name: "Total Return", ticker: "SPY"},
{ name: "Positions Held", ticker: "IWM"},
{ name: "Add Position", ticker: "Gold"},],
}
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;
}
componentDidMount() {
this.totalPortfolio()
.then(portfolioTotal => {
this.setState({
portfolioTotal
});
})
.catch(error => {
// add any required error handling/messaging here
});
}
render(){
const { portfolioTotal } = this.state;
return(
<div className="positioning">
<div className="StockCardTitle">
<img src={Folder} className="StockCardTitle-image" />
{portfolioTotal}
</div>
</div>
)
}
}
export default TitleCards;
状态发生变化并传递给 TitleCard 组件的父组件(如果有帮助的话)。
import React, { Component } from 'react';
import StockCard from "./StockCard";
import TitleCards from "./TitleCards";
import { IEX } from "./IEX.js";
const LOGO_API = "https://eodhistoricaldata.com/img/logos/US/";
class UserInput extends Component {
constructor(props){
super(props)
this.state ={
tickerName: "",
sAmtPurch: "",
sPurchPrice: "",
sDatePurch: "",
tickerList: [
{ tick: "AAPL", amtPurch: 50, purchPrice: 10, datePurch: "01/01/2021"},
{ tick: "GOOG", amtPurch: "40", purchPrice: "10", datePurch: "01/01/2021"},
{ tick: "TSLA", amtPurch: "40", purchPrice: "10", datePurch: "01/01/2021"},
{ tick: "J", amtPurch: "40", purchPrice: "10", datePurch: "01/01/2021"},
{ tick: "AMZN", amtPurch: "40", purchPrice: "10", datePurch: "01/01/2021"},
{ tick: "FB", amtPurch: "40", purchPrice: "10", datePurch: "01/01/2021"},
{ tick: "BABA", amtPurch: "40", purchPrice: "10", datePurch: "01/01/2021"},
{ tick: "JNJ", amtPurch: "40", purchPrice: "10", datePurch: "01/01/2021"},
{ tick: "JPM", amtPurch: "40", purchPrice: "10", datePurch: "01/01/2021"},
{ tick: "XOM", amtPurch: "30", purchPrice: "10", datePurch: "01/01/2021"},
],
data4: {}
}
this.handler = this.handler.bind(this)
}
handleSubmit = (event) => {
event.preventDefault()
// Initialize state into variables
const tickerToBeAdded = { tick: this.state.tickerName, amtPurch: this.state.sAmtPurch, purchPrice: this.state.sPurchPrice, datePurch: this.state.sDatePurch};
const tickerList = this.state.tickerList;
// Apend tickerList with inputed ticker
const length = tickerList.length;
tickerList[length] = tickerToBeAdded;
this.setState({
tickerList: tickerList
})
}
handleInputChange = (event) => {
event.preventDefault()
// Store Input in State
this.setState({
[event.target.name]: event.target.value
})
}
componentDidMount() {
// query the api
const url4 = `${IEX.base_url}/stock/${this.state.tickerList.tick}/intraday-prices?chartLast=1&token=${IEX.api_token}`;
fetch(url4)
.then((response) => response.json())
.then((data4) => {
this.setState({
data4: data4[data4.length - 1],
});
});
}
render () {
return (
<div>
<form onSubmit={this.handleSubmit}>
<p><input type='text' placeholder='Stock Ticker' name='tickerName' onChange={this.handleInputChange}/></p>
<p><input type='text' placeholder='Shares' name='sAmtPurch' onChange={this.handleInputChange}/></p>
<p><input type='text' placeholder='Purchase Price' name='sPurchPrice' onChange={this.handleInputChange}/></p>
<p><button>Send Message</button></p>
</form>
<div className="Charts">
<TitleCards info={this.state.tickerList}/>
</div>
</div>
)
}
}
export default UserInput;
答案 0 :(得分:1)
componentDidMount
每个坐骑只触发一次。如果你想在每次组件重新渲染时运行一些东西,你需要 componentDidUpdate
。看看这个 lifecycle diagram 使用什么方法。
将 componentDidUpdate
与 this.setState
一起使用时要小心。如果你在 componentDidUpdate 的每个周期盲目更新状态,你将触发一个无限循环。 (有关详细信息,请参阅 this answer。)