javascript - 对 props 块组件中的本机回调函数做出反应以重新渲染
问题描述
我有这个反应原生组件,它创建一个带有增加和减少按钮的通用数字输入。
export default function NumberInput({quantity = 0, onquantityChange}) {
const [number, SetNumber] = useState(quantity);
function handleIncrease() {
SetNumber(number + 1);
onquantityChange(quantity + 1);
}
function handleDecrease() {
if (number > 0) {
SetNumber(number - 1);
onquantityChange(quantity - 1);
}
}
return (
<View style={styles.container}>
<TouchableOpacity onPress={handleDecrease} activeOpacity={0.6}>
<Icon name="minus" size={20} color={colors.white} style={styles.icon} />
</TouchableOpacity>
<AppText style={styles.text}>{number}</AppText>
<TouchableOpacity onPress={handleIncrease} activeOpacity={0.6}>
<Icon name="plus" size={20} color={colors.white} style={styles.icon} />
</TouchableOpacity>
</View>
);
}
当我按下 + 或 - 按钮时,onquantityChange
功能会使数字的增加和减少变慢,如果我评论它,它将几乎实时重新渲染。(onquantityChange
函数在父函数中做了一些繁重的工作)。
我也用过这个版本,稍微好一点但没有太大变化:
const [number, SetNumber] = useState(quantity);
function handleIncrease() {
SetNumber(number + 1);
}
useEffect(() => {
onquantityChange(number);
}, [number]);
function handleDecrease() {
if (number > 0) {
SetNumber(number - 1);
}
}
我该怎么做才能使数字和 UI 重新呈现并且不等待onquantityChange
?
解决方案
通过setTimeout
在 useEffect 中使用,我们可以使onquantityChange
每次number
更改时都不运行,setTimeout 也可以在“堆栈为空时”运行它。
在主线程上的堆栈为空之前,您传递给这些函数的回调无法运行。
引用MDN
所以我把我的功能组件改成了这个。
//this have to be outside of the function component.
let changeTimeout;
export default function NumberInput({value = 0, onChange}) {
const [number, SetNumber] = useState(value);
function handleIncrease() {
SetNumber(number + 1);
}
//use setTimeout to delay onChange to a time when main thread is available
useEffect(() => {
changeTimeout && clearTimeout(changeTimeout);
changeTimeout = setTimeout(() => {
onChange(number);
}, 500);
}, [number]);
function handleDecrease() {
if (number > 0) {
SetNumber(number - 1);
}
}
return (
<View style={styles.container}>
<TouchableOpacity onPress={handleDecrease} activeOpacity={0.7}>
<Icon name="minus" size={20} color={colors.white} style={styles.icon} />
</TouchableOpacity>
<AppText style={styles.text}>{number}</AppText>
<TouchableOpacity onPress={handleIncrease} activeOpacity={0.7}>
<Icon name="plus" size={20} color={colors.white} style={styles.icon} />
</TouchableOpacity>
</View>
);
}
欢迎任何其他建议。
推荐阅读
- gnuplot - 如何 sprintf() Gnuplot 键中的最后一个数据值?
- c# - 我无法对标准按钮进行正常舍入
- javascript - 循环遍历 JavaScript 中的嵌套对象
- sas - 使用 SAS 宏
- node.js - 如何使用 JWT 以角度从中心域登录到子域?
- .net - 如何使用 xmldocument 安装 nuget 包
- c# - 使用 FluentAssertion 时 Visual Studio 警告 CA1806 的错误识别(不要忽略方法结果)
- bash - 在子目录.sh 上使用makefile 变量?
- routes - 在 Ionic5 和 Angular 路由器中传递返回导航数据
- javascript - 通过javascript创建所有标记时,JS无法将EventListener添加到按钮元素