React Native 彈窗組件優化實戰:解決 Modal 閃爍與動畫卡頓問題

📌 前言

在移動端開發中,用戶對動畫的流暢性和過渡自然性有著極高的期待。最近我對一個使用 react-native-modal 實現的 Alert 彈窗組件進行了優化,成功解決了閃爍和卡頓問題,并顯著提升了用戶體驗。

本篇博客將帶你深入了解優化的全過程,并提供完整可復用的解決方案。


🎯 問題描述

原始彈窗組件邏輯如下:

  • 使用 bounceIn / bounceOut 實現進出場動畫

  • 動畫過程中出現閃爍現象

  • 使用狀態控制不夠精準,組件經常在動畫未完成時就被卸載

  • 倒計時邏輯不夠魯棒,容易導致重復調用


🛠? 解決方案

1. 替換動畫效果

將動畫更換為更平滑的 fadeInfadeOut,避免抖動與視覺突兀感:

animationIn="fadeIn"
animationOut="fadeOut"
animationInTiming={300}
animationOutTiming={300}
backdropTransitionInTiming={0}
backdropTransitionOutTiming={0}

2. 狀態控制組件顯示

引入 isVisible 狀態,在動畫完成后再卸載組件,確保動畫完整播放:

useEffect(() => {if (visible) {setIsVisible(true);} else {const timer = setTimeout(() => {setIsVisible(false);}, 300); // 動畫時長return () => clearTimeout(timer);}
}, [visible]);

3. 使用 useNativeDriver 提升動畫性能

開啟原生線程驅動動畫,大幅度減少 JavaScript 主線程阻塞帶來的卡頓問題:

useNativeDriver

4. 自動跳轉邏輯優化

精簡并修復倒計時邏輯,避免 setInterval 注冊沖突:

useEffect(() => {setCounting(autoSend);
}, [autoSend]);useEffect(() => {if (autoSend) {timer.current = setInterval(() => {if (countNumber <= 1) {onOk();setCounting(false);return;}setCountNumber(prev => prev - 1);}, 1000);return () => clearInterval(timer.current);}
}, [countNumber]);

🧩 完整優化代碼

import React, { useRef, useState, useEffect } from 'react';
import { Text, View } from 'react-native';
import Modal from 'react-native-modal';
import Button from '../Button';
import { Props } from './types';
import styles from './styles';const Alert: React.FC<Props> = ({animationIn = 'fadeIn',animationOut = 'fadeOut',visible = false,onOk = () => {},onCancel,cancelText = '取消',okText = '立即前往',customStyles,children,title,subtitle,subtitleTwo,autoSend,onBackdropPress = true,
}) => {const [countNumber, setCountNumber] = useState(3);const [counting, setCounting] = useState(false);const timer: any = useRef(null);const [isVisible, setIsVisible] = useState(false);useEffect(() => {if (visible) {setIsVisible(true);} else {const timer = setTimeout(() => {setIsVisible(false);}, 300);return () => clearTimeout(timer);}}, [visible]);useEffect(() => {setCounting(autoSend);}, [autoSend]);useEffect(() => {if (autoSend) {timer.current = setInterval(() => {if (countNumber <= 1) {onOk();setCounting(false);return;}setCountNumber(prev => prev - 1);}, 1000);return () => clearInterval(timer.current);}}, [countNumber]);if (!isVisible && !visible) {return null;}return (<ModalisVisible={visible}animationIn={animationIn}animationOut={animationOut}backdropTransitionOutTiming={0}backdropTransitionInTiming={0}animationInTiming={300}animationOutTiming={300}useNativeDriveronBackdropPress={onBackdropPress ? onCancel : () => {}}><View style={[styles.container, customStyles?.container]}>{typeof title === 'string' ? <Text style={styles.title}>{title}</Text> : title}{typeof subtitle === 'string' ? <Text style={styles.subtitle}>{subtitle}</Text> : subtitle}{typeof subtitleTwo === 'string' ? (<Text style={[styles.subtitleTwo, customStyles?.subtitleTwo]}>{subtitleTwo}</Text>) : (subtitleTwo)}{children}<View style={[styles.button, customStyles?.button]}>{okText && (<Buttontitle={counting ? `${okText}(${countNumber}s)` : okText}blockonPress={onOk}/>)}{cancelText && (<Button title={cancelText} block type="text" onPress={onCancel} />)}</View></View></Modal>);
};export default Alert;

? 優化效果總結

項目優化前優化后
動畫流暢度有抖動、閃爍平滑、自然
動畫卸載過早卸載動畫結束后卸載
組件性能JS 主線程處理原生驅動
倒計時準確性有異常精準觸發

📎 技術建議

  • 彈窗組件最好 延遲卸載,否則動畫會被打斷

  • 不建議使用過于夸張的動畫效果,如 bounceInzoomIn,在 UX 層面可能不友好

  • useNativeDriver 是優化 React Native 動畫的必備武器

  • 注意 setIntervaluseEffect 的依賴管理,避免邏輯混亂


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/909259.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/909259.shtml
英文地址,請注明出處:http://en.pswp.cn/news/909259.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

智能客服系統開發方案:RAG+多智能體技術實現

智能客服系統開發方案:RAG+多智能體技術實現 一、系統架構設計 #mermaid-svg-hKDXil2J0xV064Q5 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hKDXil2J0xV064Q5 .error-icon{fill:#552222;}#mermaid-svg-hKDXil2…

【Kafka】消息隊列Kafka知識總結

【Kafka】消息隊列Kafka知識總結 【一】消息隊列【1】什么是消息隊列【2】消息隊列有什么用&#xff08;1&#xff09;異步處理&#xff08;2&#xff09;削峰/限流&#xff08;3&#xff09;降低系統耦合性&#xff08;4&#xff09;實現分布式事務&#xff08;5&#xff09;順…

微信小程序開發 RangeError: Maximum call stack size exceeded

通常是由于??調用棧深度超限??&#xff08;如無限遞歸、過深的函數調用鏈或數據綁定循環&#xff09;導致。以下是具體解決方案&#xff1a; 一、核心原因分析 ??無限遞歸?? 函數直接或間接調用自身且無終止條件&#xff0c;例如事件處理函數中錯誤觸發自身。??數據…

mapbox進階,切片網格生成實現

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言1.1 ??mapboxgl.Map 地圖對象1.2 ??mapboxgl.Map style屬性1.3 ??line線圖層樣式1.4 ??symbol符號圖層…

Mysql 函數concat、concat_ws和group_concat

1.concat concat()函數是將多個字符串組合在一起&#xff0c;形成一個大的字符串&#xff1b;如果連接的字符串中存在一個為NULL&#xff0c;則輸出的結果為NULL&#xff0c;語法格式為&#xff1a; concat(str1,str2,....strn) -- 1、字符之間不加連接符 mysql> select c…

“在同一事務中“ 的含義

一、"在同一事務中" 的核心含義 "在同一事務中" 指多個數據庫操作共享同一個事務上下文&#xff0c;具有以下特點&#xff1a; 原子性保證&#xff1a;所有操作要么全部成功提交&#xff0c;要么全部失敗回滾。隔離性共享&#xff1a;操作使用相同的隔離…

【Create my OS】從零編寫一個操作系統

前言&#xff1a; 相信每個自學操作系統的同學&#xff0c;大致學習路線都離不開 HIT-OS、MIT-6.S081、MIT-6.824、MIT-6.828等經典的公開課。但學習完這些經典公開課并完成相應的Lab&#xff0c;很多同學腦海中對于操作系統的知識其實都是零散的&#xff0c;讓你從頭開始編寫一…

計算機視覺與深度學習 | 低照度圖像增強算法綜述(開源鏈接,原理,公式,代碼)

低照度圖像增強算法綜述 1 算法分類與原理1.1 傳統方法1.2 深度學習方法2 核心算法詳解2.1 多尺度Retinex (MSRCR) 實現2.2 SCI自校準光照學習2.3 自適應伽馬校正2.4 WaveletMamba架構3 開源資源與實現3.1 主流算法開源庫3.2 關鍵代碼實現4 評估與實驗對比4.1 客觀評價指標4.2 …

【工具教程】批量PDF識別提取區域的內容重命名,將PDF指定區域位置的內容提取出來改名的具體操作步驟

在企業運營過程中&#xff0c;時常會面臨處理海量 PDF 文件的挑戰。從 PDF 指定區域提取內容并用于重命名文件&#xff0c;能極大地優化企業內部的文件管理流程&#xff0c;提升工作效率。以下為您詳細介紹其在企業中的應用場景、具體使用步驟及注意事項。? 詳細使用步驟? 選…

【Java多線程從青銅到王者】定時器的原理和實現(十一)

定時器 定時器時我們日常開發中會用到的組件工具&#xff0c;類似于一個"鬧鐘"&#xff0c;設定一個時間&#xff0c;等到了時間&#xff0c;定時器最自動的去執行某個邏輯&#xff0c;比如博客的定時發布&#xff0c;就是使用到了定時器 Java標準庫里面也提供了定時…

深入剖析AI大模型:Prompt 優化的底層邏輯

記得看到一篇NLP的文章&#xff0c;就 Prompt 時序效應的論文揭示了一個有趣現象&#xff0c;文章中說&#xff1a;模型對指令的解析存在 "注意力衰減" 特性 —— 就像人類閱讀時會更關注段落開頭&#xff0c;模型對 Prompt 前 20% 的內容賦予的權重高達 60%。這個發…

【備忘】PHP web項目一般部署辦法

【PHP項目一般部署辦法】 操作步驟 代碼&#xff1a; 把php項目代碼clone到指定位置如www/下新建php站點&#xff0c;填寫域名&#xff0c;把站點根目錄設置為項目根目錄項目入口設置&#xff0c;一般為public/項目權限改為766(特殊時候可設置為777)&#xff0c;如果有特殊要求…

【60 Pandas+Pyecharts | 箱包訂單數據分析可視化】

文章目錄 &#x1f3f3;??&#x1f308; 1. 導入模塊&#x1f3f3;??&#x1f308; 2. Pandas數據處理2.1 讀取數據2.2 數據信息2.3 去除訂單金額為空的數據2.5 提取季度和星期 &#x1f3f3;??&#x1f308; 3. Pyecharts數據可視化3.1 每月訂單量和訂單金額分布3.2 各季…

玩轉Docker | 使用Docker部署vaultwarden密碼管理器

玩轉Docker | 使用Docker部署vaultwarden密碼管理器 前言一、vaultwarden介紹Vaultwarden 簡介主要特點二、系統要求環境要求環境檢查Docker版本檢查檢查操作系統版本三、部署vaultwarden服務下載vaultwarden鏡像編輯部署文件創建容器檢查容器狀態檢查服務端口安全設置四、配置…

晶振的多面舞臺:從日常電子到高精尖科技的應用探秘

在現代科技的宏大舞臺上&#xff0c;晶振宛如一位低調卻至關重要的幕后主角&#xff0c;以其穩定的頻率輸出&#xff0c;為各類電子設備賦予了精準的“脈搏”。從我們日常生活中須臾不離的電子設備&#xff0c;到引領時代前沿的高精尖科技領域&#xff0c;晶振都發揮著不可替代…

uni-app 小程序 Cannot read property ‘addEventListener‘ of undefined, mounted hook

在用 uni-app 開發微信小程序時&#xff0c;提示 Cannot read property addEventListener of undefined, mounted hook document.addEventListener("mousemove", this.touchmove) 在小程序開發里&#xff0c;addEventListener 并非通用的標準 API&#xff0c;不過與…

《專業小詞開課啦》——冪等

在系統對接過程中&#xff0c;當出現接口調用異常的情況時&#xff0c;程序員可能會用一些專業術語來答疑......對于0基礎同學&#xff0c;自然是需要自行百度一番&#xff0c;學習一下&#xff01; 接下來&#xff0c;先學習【冪等】 PS&#xff1a; 小白參考1.1~1.4內容即…

滲透實戰PortSwigger Labs指南:自定義標簽XSS和SVG XSS利用

阻止除自定義標簽之外的所有標簽 先輸入一些標簽測試&#xff0c;說是全部標簽都被禁了 除了自定義的 自定義<my-tag onmouseoveralert(xss)> <my-tag idx onfocusalert(document.cookie) tabindex1> onfocus 當元素獲得焦點時&#xff08;如通過點擊或鍵盤導航&…

利用pycharm搭建模型步驟

1 如何將別人論文的代碼跑起來&#xff0c;以Pycharm為例&#xff0c;在下載代碼的時候&#xff0c;要注意使用的python版本是多少&#xff0c;并且要注意使用的keras和tensorflow等文件夾的版本&#xff0c;我們可以直接使用pycharm中file文件中的settings&#xff0c;來添加相…

Qt 中directoryChanged監聽某個目錄的內容是否發生變化

Qt 中&#xff0c;directoryChanged 是 QFileSystemWatcher 類的一個信號&#xff0c;用于監聽某個目錄的內容是否發生變化&#xff08;如添加、刪除文件或子目錄&#xff09; ? 一、功能說明 QFileSystemWatcher::directoryChanged(const QString &path) 信號的作用是&…