React Native进度条动画触发MapView重绘无法拖动的解决方法问询
问题根因
- Home组件的
progressValue状态每秒更新一次,会触发整个Home组件重渲染,子组件MainMap默认会跟随父组件重绘。 - MainMap内的Marker使用动态生成的
Date.now()作为key,每次重绘key都会变化,React会强制销毁重建Marker节点,进一步导致MapView被强制刷新,拖动动作直接被中断。
解决步骤
1. 用React.memo包裹MainMap组件,阻止非必要重渲染
给MainMap包一层React.memo,它会对传入的props做浅比较,只要notification和其他传入的props没有实际变化,就不会触发MainMap的重绘:
// MainMap 组件定义处修改 const MainMap = React.memo(({ notification }) => { // 原有组件逻辑完全不变 })
如果MainMap还接收其他引用类型的props(比如回调函数),需要在Home组件中用useCallback包裹对应的回调后再传入,避免浅比较失效。
2. 替换Marker的动态key为固定值
把两个Marker的key替换为固定的唯一标识,避免每次渲染都重建Marker:
{geo.location && <Marker identifier={'me'} pinColor={"red"} key="current-user-marker" title={"Это я"} coordinate={geo.location} /> } {notification && <Marker identifier={'target'} pinColor={COLORS.primary} key="notification-marker" title={"Помогите!"} coordinate={notification.request.content.data.loc} /> }
3. 可选优化:用Animated API实现进度条,彻底避免父组件重绘
react-native的Animated动画值更新默认不会触发组件重渲染,比每秒更新state的性能好很多,可以直接替换原有进度条实现逻辑:
// Home组件内替换原有progressValue的定义 const progressAnim = useRef(new Animated.Value(0)).current; useEffect(() => { let timer; if (progressAnim._value != 0) { timer = setInterval(() => { if (progressAnim._value <= 1) { progressAnim.setValue(progressAnim._value + 0.04); } else { progressAnim.setValue(0); setTimeOver(true); } }, 1000); return () => clearInterval(timer); } }, [progressAnim]); // 进度条组件直接绑定动画值即可,react-native-elements的ProgressBar支持animated属性 <ProgressBar progress={progressAnim} animated />
内容的提问来源于stack exchange,提问作者an92kz
相关产品推荐
相关产品推荐

