我有这个钩子用来抽象SELECT *
FROM (SELECT t1.*,
Row_number()
OVER(
partition BY t1.alerttype, t1.alerttypeid, t1.macid
ORDER BY t1.timestamp DESC) rn
FROM alert_details
LEFT JOIN alert_details_status t2
ON macid = c.macid
AND t1.alerttypeid = t2.alerttypeid
AND t1.alerttype = t2.alerttype
AND t2.is_notified = true
AND t2.escalation_status = 'completed'
WHERE t2.alerttypeid IS NULL) t
WHERE t.rn = 1
:
requestAnimationFrame
它的用法如下:
export const useAnimationIncrease = ({
easingName = EasingName.linear,
diff: end,
duration = 500
}: AnimationIncreaseProps) => {
const [increase, setIncrease] = useState(0);
const start = useRef<any>(null);
useLayoutEffect(() => {
let raf: number;
const frame = (timestamp: number) => {
if (!start.current) {
start.current = timestamp;
}
const time = timestamp - start.current;
// get percent of completion in range [0, 1]
const percentRange = Math.min(time / duration, 1);
const percent = easing[easingName as string](percentRange);
setIncrease(increase + end * percent);
if (time < duration) {
raf = requestAnimationFrame(frame);
}
};
raf = requestAnimationFrame(frame);
return () => {
cancelAnimationFrame(raf);
};
}, [end]);
return increase;
};
每次都会返回增加的值,因此我可以将其用于滚动等。
我该如何在单击按钮时触发此操作?或者我正在解决此错误。
如果我尝试这个;
const increase = useAnimationIncrease({ easingName: EasingName.inOutCubic, diff: 10 });
然后我收到错误消息:
只能在函数组件的主体内部调用钩子。
答案 0 :(得分:4)
根据钩子规则
仅位于顶层的呼叫挂钩
请勿在循环,条件或嵌套函数中调用Hook。 相反,请始终在您的React函数的顶层使用挂钩。通过 遵循此规则,请确保在相同的位置调用钩子 每次渲染组件时订购。这就是让React能够 正确保留多个useState与之间的Hooks状态 useEffect调用。 (如果您有好奇心,我们将对此进行详细说明
由于您通过在onClick
事件处理程序中调用钩子违反了该规则,因此您将收到此警告
作为解决方法,您可以设置一个变量来触发动画
export const useAnimationIncrease = ({
easingName = EasingName.linear,
diff: end,
duration = 500
}: AnimationIncreaseProps) => {
const [increase, setIncrease] = useState(0);
const [startAnimation, setStartAnimation] = useState(0);
const start = useRef<any>(null);
useLayoutEffect(() => {
let raf: number;
const frame = (timestamp: number) => {
if (!start.current) {
start.current = timestamp;
}
const time = timestamp - start.current;
// get percent of completion in range [0, 1]
const percentRange = Math.min(time / duration, 1);
const percent = easing[easingName as string](percentRange);
setIncrease(increase + end * percent);
if (time < duration) {
raf = requestAnimationFrame(frame);
}
};
raf = requestAnimationFrame(frame);
return () => {
cancelAnimationFrame(raf);
};
},[end, startAnimation]);
return [increase, startAnimation, setStartAnimation];
};
并像使用它
const [increase, startAnimation, setStartAnimation] = useAnimationIncrease({ easingName: EasingName.inOutCubic, diff: 10 });
onClick={(e) => {
setStartAnimation(prev => prev + 1);
// use increase now
}