[英]React componentDidMount() initializing state
在React的一個小項目上工作,我正在使用Axios從經過測試工作的API中獲取信息。 問題是當我提取數據並嘗試更新組件狀態時,來自API的值沒有被填充到要在組件中呈現的狀態中。
我一直在嘗試使數據處於這種狀態:
componentDidMount() {
this.state.databases.forEach(d => {
axios.get(`http://localhost:3204/customer/${d}/count`).then(value => {
this.setState({ counts: this.state.counts.push(value.data) });
});
});
console.log(this.state);
}
以前的版本是這樣寫的:
componentDidMount() {
let internalCounts = [];
this.state.databases.forEach(d => {
axios.get(`http://localhost:3204/customer/${d}/count`).then(value => {
internalCounts.push(value.data);
});
});
this.setState({count: internalCounts});
}
兩種情況最終都有相同的結果。 狀態永遠不會真正用新的count數組更新。 我懷疑這是由於Axios
和 setState
的異步特性引起的。
一種簡單有效的方法來使這兩個人停止比賽?
在第一個版本中,您正確地認為這是由於服務的異步性質所致。 您正在記錄輸出,但這是在服務解決之前發生的。
在第二個(上一個)示例中,您要在狀態解析之前進行設置。 我建議采用以下方法,創建一個promise數組,然后在更新狀態之前等待所有promise解析:
componentDidMount() { const promises = []; this.state.databases.forEach(d => { promises.push(axios.get(`http://localhost:3204/customer/${d}/count`)); }); Promise.all(promises).then(results => { const internalCounts = []; results.map(result => { internalCounts.push(result.data); }); this.setState({count: internalCounts}); }) }
設置狀態后不要立即使用console.log
,因為它是異步的。 通過對setState
的回調來實現。
this.setState({...}, () => console.log(...))
或使用console.log
在渲染方法中檢查狀態
另外,不要對forEach
這樣做,而是嘗試一次通過Promise.all
一次提出所有請求。
componentDidMount() {
const promiseArray = this.state.databases.map( d =>
axios.get(`http://localhost:3204/${d}/count`)
)
Promise.all( promiseArray )
.then( ( results ) => {
const data = results.map( result => result.data);
this.setState( prevState => ({
counts: [ ...prevState.counts, ...data]
}))
})
}
您的代碼有一些問題:
Array.prototype.push(value.data)
返回新的長度,而不是新的數組。 因此this.setState({ counts: this.state.counts.push(value.data) });
正在將state.counts
轉換為數字值this.state.counts.length + 1
,這可能是不希望的。 console.log(this.state);
應該放在setState()
的回調參數中。 setState
之前等待axios調用。 您的想法正確。 問題是我試圖改變狀態。 (我一直對不可變數據感到恐懼...。因此我必須習慣一些東西。)
我的解決方案代碼如下:
componentDidMount(){
this.state.databases.forEach(d => {
axios.get(`http://localhost:3204/${d}/count`).then(value => {
this.setState(prevState => ({
counts: [...prevState.counts, value.data]
}));
});
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.