樓樓今日遇到個坑爹的問題。
就是 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...
來源:掘金
著作權歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權,非商業(yè)轉(zhuǎn)載請注明出處。
樓上的回答有一點缺陷。
白天我看到這個問題也是這么想的,可是setState及render并沒有自帶的shallow compare,猜想不成立。剛才自己試了一下,即使是空的setState也可以觸發(fā)當前組件re-render。
至于題目中出現(xiàn)的情況,我猜測有fetch的容器組件跟列表項展示組件是分開的,同時展示組件使用了PureComponent或者在ShouldComponentUpdate中做了shallow compare,或者是其他的節(jié)流方案??傊畬τ诓桓淖兊刂返?code>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相當于直接改變了數(shù)組對應的內(nèi)存塊,這樣修改,react內(nèi)部用來做對比的imageList也被你改了,因為都是指向同一塊內(nèi)存。最后re-render的時候,react發(fā)現(xiàn)你的imageList是一樣的,好的,沒有變化,不更新了。
你可以這么做:
// 使用新的數(shù)組
var lists = [...this.state.imageList];
// 其他語句不變北大青鳥APTECH成立于1999年。依托北京大學優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達內(nèi)教育集團成立于2002年,是一家由留學海歸創(chuàng)辦的高端職業(yè)教育培訓機構,是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學校辦產(chǎn)業(yè)為響應國家深化產(chǎn)教融合/校企合作的政策,積極推進“中國制造2025”,實現(xiàn)中華民族偉大復興的升級產(chǎn)業(yè)鏈。利用北京大學優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓領域的先行者
曾工作于聯(lián)想擔任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍懿科技有限責任公司從事總經(jīng)理職務負責iOS教學及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術, 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術功底深厚。 授課風格 授課風格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術顧問,美國Dachieve 系統(tǒng)架構師,美國AngelEngineers Inc. 系統(tǒng)架構師。