[英]setState while looping through an array of props - React ComponentDidUpdate
我正在做一個項目,需要在 componentDidMount 之后設置狀態。(期望子組件中的道具是在掛載時派生的。因此我只能在之后設置狀態)我能想出的唯一選項是使用 componentDidUpdate。
props 父組件是一個從 axios 獲取的數據派生的數組。
這里的目標是遍歷數組並從下面代碼中顯示的 URL 中獲取每個數組的數據,然后設置子組件的 setState。
嘗試我通常做的事情,我無法停止在 componentDidUpdate 處觸發的無限循環。
這是我的代碼。
家長
render(){
return (
<div className="App">
<EachCountry countryList= {this.state.CountriesList}/>
</div>
子組件
async componentDidUpdate(prevProps, prevState, snapshot){
if(this.state.countryList.length < this.props.countryList.length){
await this.props.countryList.map(m=>{
axios ({
method:"get",
url:`/countryupdate/${m}`
}).then(res=>{
console.log(res.data)
this.setState(crntState=>({
countryList:[...crntState.countryList, res.data]
}))
})
})
}
}
控制台日志工作得很好。 但是當我嘗試 setState 時,我遇到了像 5000 條錯誤消息這樣的無限循環。
我的另一個技巧是
async componentDidUpdate(prevProps, prevState, snapshot){
if(this.state.countryList.length < this.props.countryList.length){
await this.props.countryList.map(m=>{
var newdata = axios ({
method:"get",
url:`/countryupdate/${m}`
})
console.log(newdata)
this.setState(crntState=>({
countryList:[...crntState.countryList, newdata.data]
}))
})
}
}
而這個返回的是承諾而不是所需的數據。
幫助家庭
我錯過了什么?
Your issue is likely caused by derived state: state that is dependent on props and is an anti pattern in react: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state .html#when-to-use-derived-state
請參閱下面的可行解決方法,但建議您重組數據流。
嘗試這樣的事情,首先只向 state 發送 1 個更新:
async componentDidMount(){
//variable to store new data
const allNewData = [];
//an async data fetcher
const getNewData = async(m) => {
let newData = await axios({
method: "get",
url: `/countryupdate/${m}`
})
allNewData.push(newData.data);
}
//an async for loop
async function updateData() {
for (const m of countryList) {
await getNewData(m);
}
this.setState(crntState => ({
countryList: [...crntState.countryList, ...allNewData]
}))
}
await updateData();
}
如果上述方法不起作用(可能不起作用),則使用 getDerivedStateFromProps 而不是 componentDidMount 並將 setState 替換為 return obj
static getDerivedStateFromProps(props, state) {
if (this.state.countryList.length < this.props.countryList.length) {
...
return {
countryList: [...state.countryList, ...allNewData]
};
}
let newState = await updateData();
return newState;
}
如果這不起作用,則恢復到 componentDidMount 並使用 shouldComponentUpdate 作為條件
shouldComponentUpdate(nextProps, nextState) {
return this.state.countryList.length != nextState.countryList.length;
}
如果我沒有得到正確的語法,請查看此代碼片段
function mockAxios(m) { return new Promise(function(resolve, reject) { setTimeout(() => resolve({ data: `${m}'s data` }), 1000) }); } function setState(arr) { console.log(arr); console.log("state has been set") } const countryList = ["A", "B", "C", "D", "E"]; /////////////////////////////////////////////// async function componentDidMount() { const allNewData = []; async function getNewData(m) { let newData = await mockAxios(m); allNewData.push(newData.data); } async function updateData() { for (const m of countryList) { await getNewData(m); console.log("fetching data...") } setState(allNewData); } await updateData(); } componentDidMount();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.