let 变量在 useImperativeHandle 函数中未定义
let variable is undefined in useImperativeHandle function
我在 React Native (Expo) 下的 .web.js 文件中使用 lottie-web 包。
我的问题是 let 变量 anim 在 useImperativeHandle 的函数中未定义。在 useEffect 动画中效果非常好。例如,如果我在 useEffect 初始化后立即访问 anim.play() ,它就可以工作。但是在命令式的 play() 函数中它不起作用。
在我的父组件中,我使用 useRef 创建一个 ref 并将该 ref 传递给组件
const lottieAnim = useRef(null);
--
let anim;
useEffect(() => {
const lottieOptions = {
container: divContainer.current,
renderer: 'svg',
loop,
autoplay,
segments: segments !== false,
animationData,
rendererSettings,
};
anim = lottie.loadAnimation({ ...lottieOptions, ...options });
// anim.play(); works here
if (onAnimationFinish) {
anim.addEventListener('complete', onAnimationFinish);
}
}, []);
useImperativeHandle(ref, () => ({
stop() {
anim.stop();
},
pause() {
anim.pause();
},
play() {
anim.play();
// anim is undefined
},
setSpeed(s) {
anim.setSpeed(s);
},
setDirection(d) {
anim.setDirection(d);
},
playSegments(s) {
anim.playSegments(s);
},
}));
那是因为 React 在 useImperativeHandle 中创建 API 函数时不知道动画是什么(由于闭包和反应更新策略不会通过改变变量触发任何更新)。有一些方法可以解决这个问题,毕竟这是个人意见,我会使用这样的方法,效果最好
对我来说。
添加GetApi函数
// hanlder.js
const stop = anim => anim.stop()
// api.js
const getAPI = anim => () => ({
stop: stop.bind(this, anim),
// or simply
setSpeed: s => anim.setSpeed(s),
// you can mock APIs here if anim is null or throw an Error
});
在状态中存储动画
store anim in the state for first render only and use it in dependencies array of getApi useEffect
const [anim, setAnim] = React.useState(null);
React.useEffect(() => {
// initialization part
}, []);
React.useImperativeHandle(ref, getAPI(anim), [anim]);
我在 React Native (Expo) 下的 .web.js 文件中使用 lottie-web 包。
我的问题是 let 变量 anim 在 useImperativeHandle 的函数中未定义。在 useEffect 动画中效果非常好。例如,如果我在 useEffect 初始化后立即访问 anim.play() ,它就可以工作。但是在命令式的 play() 函数中它不起作用。
在我的父组件中,我使用 useRef 创建一个 ref 并将该 ref 传递给组件
const lottieAnim = useRef(null);
--
let anim;
useEffect(() => {
const lottieOptions = {
container: divContainer.current,
renderer: 'svg',
loop,
autoplay,
segments: segments !== false,
animationData,
rendererSettings,
};
anim = lottie.loadAnimation({ ...lottieOptions, ...options });
// anim.play(); works here
if (onAnimationFinish) {
anim.addEventListener('complete', onAnimationFinish);
}
}, []);
useImperativeHandle(ref, () => ({
stop() {
anim.stop();
},
pause() {
anim.pause();
},
play() {
anim.play();
// anim is undefined
},
setSpeed(s) {
anim.setSpeed(s);
},
setDirection(d) {
anim.setDirection(d);
},
playSegments(s) {
anim.playSegments(s);
},
}));
那是因为 React 在 useImperativeHandle 中创建 API 函数时不知道动画是什么(由于闭包和反应更新策略不会通过改变变量触发任何更新)。有一些方法可以解决这个问题,毕竟这是个人意见,我会使用这样的方法,效果最好 对我来说。
添加GetApi函数
// hanlder.js
const stop = anim => anim.stop()
// api.js
const getAPI = anim => () => ({
stop: stop.bind(this, anim),
// or simply
setSpeed: s => anim.setSpeed(s),
// you can mock APIs here if anim is null or throw an Error
});
在状态中存储动画
store anim in the state for first render only and use it in dependencies array of getApi useEffect
const [anim, setAnim] = React.useState(null);
React.useEffect(() => {
// initialization part
}, []);
React.useImperativeHandle(ref, getAPI(anim), [anim]);