在非 React 的事务流中避开多次渲染的问题
admin
2024-03-06 06:39:51
0

这样就可以在非 React 的事务流中避开多次渲染的问题

测试代码
import React from ‘react’;

interface State {
s1: number;
s2: number;
s3: number;
s4: number;
}

// eslint-disable-next-line @iceworks/best-practices/recommend-functional-component
export default class TestClass extends React.Component {
renderTime: number;
constructor(props: any) {
super(props);
this.renderTime = 0;
this.state = {
s1: 1,
s2: 1,
s3: 1,
s4: 1,
};
}

componentDidMount() {
const btn1 = document.getElementById(‘native-event’);
const btn2 = document.getElementById(‘native-event-async’);
btn1?.addEventListener(‘click’, this.nativeCallback);
btn2?.addEventListener(‘click’, this.nativeCallbackMerge);
}

changeNotUsedState = () => {
const { s4 } = this.state;
this.setState({ s4: s4 + 1 });
};

reactEventCallback = () => {
const { s1, s2, s3 } = this.state;
this.setState({ s1: s1 + 1 });
this.setState({ s2: s2 + 1 });
this.setState({ s3: s3 + 1 });
console.log(‘after setState s1:’, this.state.s1);
};
timerCallback = () => {
setTimeout(() => {
const { s1, s2, s3 } = this.state;
this.setState({ s1: s1 + 1 });
console.log(‘after setState s1:’, this.state.s1);
this.setState({ s2: s2 + 1 });
this.setState({ s3: s3 + 1 });
});
};
asyncCallback = () => {
Promise.resolve().then(() => {
const { s1, s2, s3 } = this.state;
this.setState({ s1: s1 + 1 });
console.log(‘after setState s1:’, this.state.s1);
this.setState({ s2: s2 + 1 });
this.setState({ s3: s3 + 1 });
});
};
nativeCallback = () => {
const { s1, s2, s3 } = this.state;
this.setState({ s1: s1 + 1 });
console.log(‘after setState s1:’, this.state.s1);
this.setState({ s2: s2 + 1 });
this.setState({ s3: s3 + 1 });
};
timerCallbackMerge = () => {
setTimeout(() => {
const { s1, s2, s3 } = this.state;
this.setState({ s1: s1 + 1, s2: s2 + 1, s3: s3 + 1 });
console.log(‘after setState s1:’, this.state.s1);
});
};
asyncCallbackMerge = () => {
Promise.resolve().then(() => {
const { s1, s2, s3 } = this.state;
this.setState({ s1: s1 + 1, s2: s2 + 1, s3: s3 + 1 });
console.log(‘after setState s1:’, this.state.s1);
});
};
nativeCallbackMerge = () => {
const { s1, s2, s3 } = this.state;
this.setState({ s1: s1 + 1, s2: s2 + 1, s3: s3 + 1 });
console.log(‘after setState s1:’, this.state.s1);
};
sameState = () => {
const { s1, s2, s3 } = this.state;
this.setState({ s1 });
this.setState({ s2 });
this.setState({ s3 });
console.log(‘after setState s1:’, this.state.s1);
};
withoutParams = () => {
this.setState({});
};

render() {
console.log(‘renderTime’, ++this.renderTime);
const { s1, s2, s3 } = this.state;
return (


React Event
Timer Callback
Async Callback
Native Event
Timer Callback Merge
Async Callback Merge
Native Event Merge
Change Not Used State
React Event Set Same State

React Event SetState Without Params


S1: {s1} S2: {s2} S3: {s3}


);
}
}
函数组件
函数组件重新渲染的条件也和类组件一样,组件的属性 Props 和组件的状态 State 有修改的时候,会触发组件重新渲染,所以类组件存在的问题,函数组件同样也存在,而且因为函数组件的 state 不是一个对象,情况就更糟糕

React 合成事件
const reactEventCallback = () => {
// S1 S2 S3 都是 1
setS1((i) => i + 1);
setS2((i) => i + 1);
setS3((i) => i + 1);
// 页面只会渲染一次, S1 S2 S3 都是 2
};
定时器回调
const timerCallback = () => {
setTimeout(() => {
// S1 S2 S3 都是 1
setS1((i) => i + 1);
setS2((i) => i + 1);
setS3((i) => i + 1);
// 页面只会渲染三次, S1 S2 S3 都是 2
});
};
异步函数回调
const asyncCallback = () => {
Promise.resolve().then(() => {
// S1 S2 S3 都是 1
setS1((i) => i + 1);
setS2((i) => i + 1);
setS3((i) => i + 1);
// 页面只会渲染三次, S1 S2 S3 都是 2
});
};
原生事件
useEffect(() => {
const handler = () => {
// S1 S2 S3 都是 1
setS1((i) => i + 1);
setS2((i) => i + 1);
setS3((i) => i + 1);
// 页面只会渲染三次, S1 S2 S3 都是 2
};
containerRef.current?.addEventListener(‘click’, handler);
return () => containerRef.current?.removeEventListener(‘click’, handler);
}, []);

相关内容

热门资讯

半两财经|中金:北京、上海楼市... 中金公司最新研报指出,历经四年深度调整,我国房地产市场正迎来结构性转机。结合供给侧出清与政策端持续发...
资本赋能战略跃迁,一家央企的五... 国有资本投资公司的新定位,正驱动这家材料巨头完成一场深刻的自我革命。 2月27日,中国建材集团202...
阿联酋股市复市即遭抛售 迪拜综... 财联社3月4日讯(编辑 史正丞)经过此前两天紧急休市后,身处中东战场一线的阿联酋资本市场周三重启交易...
从“日赚三百”到亏损累累:盈盈...   盈盈订购”APP打着现货订购的旗号,实则行非法期货交易之实,将现货交易异化为高风险的期货对赌。其...
原创 美... 近期美伊冲突的加剧引发了全球关注。原本认为美军和以色列的“斩首行动”能够迅速消除伊朗威胁,但结果却成...
中石油、中石化、中海油集体公告... 受中东地缘局势的影响,A股油气板块上演罕见大涨行情,近2个交易日,“三桶油”历史上首次集体收获两连板...
监管批复落地,秦农银行吸收合并... 3月2日,国家金融监督管理总局官网披露的批复文件显示,陕西金融监管局已正式同意陕西秦农农村商业银行股...
德邦股份:上交所受理公司股票主... 3月4日,德邦股份(603056.SH)公告称,公司拟以股东会决议方式主动撤回A股股票在上海证券交易...
排队8小时就为抢个金碗!有人请... 一只重达数公斤、标价62.75万元的“花丝真言金碗”,上架不到10分钟即被抢光;价值56万元的金葫芦...
赤子城科技发布盈喜,AI推动2... 3 月 4 日,赤子城科技(09911.HK)发布 2025 年度盈利预告,公司营收实现快速增长,利...
中文在线2025年亏损超5.8... 来源:运营商财经网 运营商财经网 赵鑫雨/文 日前,中文在线发布发布公告显示,公司已向港交所递交上市...
商道创投网·会员动态|光帆科技... 《商道创投网》2026年3月4日从官方获悉:光帆科技近日完成了由联想和小鹏旗下星航资本联合领投,高秉...
“红利+”指数集体回调,资金逆... 截至午间收盘,国证价值100指数、国证自由现金流指数均下跌0.8%,中证红利指数下跌1.6%,资金逆...
全国人大代表姚劲波:从“阿姨”... 记者 郑淯心 2026年全国两会期间,全国人大代表、58同城董事长兼CEO姚劲波围绕强化“一老一小”...
春节期间黄金消费保持强劲 来源:中国黄金网 2026年春节前夕,一场覆盖全国的“乐购新春”促消费活动为节日市场增添了强劲动力。...
金价震荡“带崩”银行交易系统!... 在国际金价持续震荡的背景下,不少投资者转向一些银行提供的具备服务时间长、申购和赎回费率低至0%等特点...
北汽集团董事长张建勇2024年... 运营商财经网 王鑫垚/文 日前,北汽集团官网披露了企业负责人2024年度的薪酬情况,该消息引起人们的...
比格披萨赴港IPO,开近400... 在绿茶集团、遇见小面港股上市后,又有餐饮公司冲击IPO。 格隆汇获悉,近期,比格餐饮国际控股有限公司...
现货黄金反弹至5100美元上方... 央广网北京3月4日消息(记者 宓迪)在昨日经历回调后,今日黄金、白银双双迎来回升,当前较高位有所回落...
阿里千问关联公司近期变更主要人... 天眼查工商信息显示,Qwen关联上海智信普惠科技有限公司成立于2025年2月,注册资本5000万人民...