这样就可以在非 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 合成事件
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);
}, []);