樓樓今日遇到個坑爹的問題。
就是 this.setStats({}) 對 this.stats 不更新問題
問題是這樣的
constructor(props) {
super(props);
this.state = {
imageList: []
}
WechatService.getMaterialOrealList("image").then((result) => {
this.setState({
imageList: result
})
});
}
async handleInputChangeUpload(event) {
var target = event.target;
var file = target.files[0];
var formData = new FormData();
formData.append('file', file);
var result = await WechatService.updateMaterialImage(formData);
var lists = this.state.imageList;
lists.push(result);
console.log(lists);
//同步更新
this.setState((prevState, props) => ({
imageList: lists
}))
}
數(shù)組的長度已經(jīng)變成了11可是 render 并沒有更新??!,這是為什么呢?
此方法已經(jīng)是谷歌出來的東西,可是好像并沒有成功
this.setState((prevState, props) => ({
imageList: lists
}))
但是樓主看了一下elementsUI 的代碼后進行一次修改后,發(fā)現(xiàn)一下方案倒是成功了。百思不得其解,不知道那位小兄弟可以解答一下。
constructor(props) {
super(props);
this.state = {
//這是把數(shù)組用一個對象包含起來
data: {
imageList: []
}
}
}
componentWillMount() {
WechatService.getMaterialOrealList("image").then((result) => {
this.setState({
data: Object.assign({}, {
imageList: result
})
})
});
}
handleUpload() {
this.refs.inputFile.click();
}
async handleInputChangeUpload(event) {
var target = event.target;
var file = target.files[0];
var formData = new FormData();
formData.append('file', file);
var result = await WechatService.updateMaterialImage(formData);
var lists = this.state.data.imageList;
lists.push(result);
this.setState((prevState, props) => ({
//淺拷貝、對象屬性的合并
data: Object.assign({}, { imageList: lists })
}))
setTimeout(() => {
console.log(this.state.data);
});
}
這樣使用對象進行修改的數(shù)組變量反而更新了。
這是為什么呢?
無法解答
作者:傻夢獸
鏈接:https://juejin.im/post/5b1a22...
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
樓上的回答有一點缺陷。
白天我看到這個問題也是這么想的,可是setState
及render
并沒有自帶的shallow compare
,猜想不成立。剛才自己試了一下,即使是空的setState
也可以觸發(fā)當(dāng)前組件re-render
。
至于題目中出現(xiàn)的情況,我猜測有fetch
的容器組件跟列表項展示組件是分開的,同時展示組件使用了PureComponent
或者在ShouldComponentUpdate
中做了shallow compare
,或者是其他的節(jié)流方案。總之對于不改變地址的imageList
數(shù)組而言,是無法觸發(fā)展示組件的re-render
的。
樓上回答的缺陷在于,如果不使用節(jié)流方案,那么React
本身不會進行任何shallow compare
,所有的變動都是基于最終得出的Vitural DOM diff
來進行的,用來對比的不是imageList
本身,而是每一個由imageList
map出來的item
。即若能觸發(fā)展示組件的re-render
,即使不改變數(shù)組的引用,依然可以正確顯示變動
var lists = this.state.imageList;
lists.push(result);
console.log(lists);
//同步更新
this.setState((prevState, props) => ({
imageList: lists
}));
有一個點你要弄清楚,在js中,數(shù)組的賦值是引用傳遞的,list.push相當(dāng)于直接改變了數(shù)組對應(yīng)的內(nèi)存塊,這樣修改,react內(nèi)部用來做對比的imageList
也被你改了,因為都是指向同一塊內(nèi)存。最后re-render的時候,react發(fā)現(xiàn)你的imageList是一樣的,好的,沒有變化,不更新了。
你可以這么做:
// 使用新的數(shù)組
var lists = [...this.state.imageList];
// 其他語句不變
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團,成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達內(nèi)教育集團成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。