React實現(xiàn)一個通用骨架屏組件示例
骨架屏是什么?
找到這里的同志,或多或少都對骨架屏有所了解,請容許我先啰嗦一句。骨架屏(Skeleton Screen)是一種優(yōu)化用戶弱網(wǎng)體驗的方案,可以有效緩解用戶等待的焦躁情緒。
Demo
先看個demo 大概了解下最終的產(chǎn)物及其使用方式
npm install obiusm-react-components
import { Skeleton } from 'obiusm-react-components';
<Skeleton isVisible={true}> <div className="wrapper"> <div className="content1"></div> <div data-skeleton-ignore={true}>123456</div> <div className="content2"></div> <div className="content3" data-skeleton-style={{ width: '50%' }}></div> </div> </Skeleton>
只需要在自己寫的組件外面包一層決定其是否顯示就可以了
設(shè)計思路
骨架可以在真實內(nèi)容沒有加載出來前讓用戶提前感知,可以提高用戶體驗 如果我們每次寫組件的時候都要為其定制骨架,那就顯得相當(dāng)繁瑣
得益于React props的這種數(shù)據(jù)數(shù)據(jù)傳遞方式,我們在props中可以輕松拿到整顆ReactElement的樹。 那么我們只需要去遞歸遍歷這個樹從而去模仿其結(jié)構(gòu),復(fù)制其class就可以實現(xiàn)自動生成骨架了。
但在具體的使用上,我們可能只需要結(jié)構(gòu)前幾層的結(jié)構(gòu)而不需要模擬整顆樹的結(jié)構(gòu),也有可能自動生成的樣式太丑我們需要定制其節(jié)點樣式,還有可能我們不需要關(guān)注一些浮層類的內(nèi)容或者說想忽略某一個節(jié)點
所以大概需要實現(xiàn)以下幾個功能
- 設(shè)定遞歸深度
- 提供忽略節(jié)點的方法
- 提供定制骨架節(jié)點樣式的方法
具體實現(xiàn)
首先定義一個組件函數(shù)來決定是渲染骨架屏還是真實元素
function Skeleton(props: Props) { if (!props) { return <div />; } if (props.isVisible) { return createModal(props.children, props.depth || 4, 0); } else { return props.children ? props.children : <div />; } }
createModal 對Skeleton下面包住的div進行遞歸遍歷, 每次遞歸的時候?qū)urrent+1并傳遞下去,這樣我們可以判斷已經(jīng)遞歸了幾層了 判斷一下每個節(jié)點上data-skeleton-ignore是否有data-skeleton-style從而特殊處理就可以了
const createModal = (child: ReactElement, depth: number, current: number) => { if ( depth === current || (child && child.props && child.props['data-skeleton-ignore']) ) { return; } if ( child && child.props && child.props.children && Array.isArray(child.props.children) && current < depth - 1 ) { return ( <div className={`${ child.props.className !== undefined ? child.props.className : '' } ${'react-skeleton'}`} style={ child.props && child.props['data-skeleton-style'] ? child.props['data-skeleton-style'] : {} } key={Math.random() * 1000} > {child.props.children && child.props.children.length > 0 ? child.props.children.map((child: any) => { return createModal(child, depth, current + 1); }) : '*'} </div> ); } else { return ( <div className={`${ child.props && child.props.className ? child.props.className : '' } ${'react-skeleton2'}`} style={ child.props && child.props['data-skeleton-style'] ? child.props['data-skeleton-style'] : {} } key={Math.random() * 1000} > * </div> ); } };
完整代碼及其使用文檔
文檔 https://magic-zhu.github.io/obiusm-react-components-docs/components/skeleton/
到此這篇關(guān)于React實現(xiàn)一個通用骨架屏組件示例的文章就介紹到這了,更多相關(guān)React 骨架屏內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Create?react?app修改webapck配置導(dǎo)入文件alias
這篇文章主要為大家介紹了Create?react?app修改webapck配置導(dǎo)入文件alias,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-1240行代碼把Vue3的響應(yīng)式集成進React做狀態(tài)管理
這篇文章主要介紹了40行代碼把Vue3的響應(yīng)式集成進React做狀態(tài)管理,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05詳解React中的useMemo和useCallback的區(qū)別
React中的useMemo和useCallback是兩個重要的Hooks。常常被用于優(yōu)化組件的性能。雖然這兩個Hooks看起來很相似,但它們彼此之間還是有很大的區(qū)別的,隨著小編一起來學(xué)習(xí)吧2023-04-04使用 Rails API 構(gòu)建一個 React 應(yīng)用程序的詳細步驟
這篇文章主要介紹了使用 Rails API 構(gòu)建一個 React 應(yīng)用程序的詳細步驟,主要包括后端:Rails API部分,前端:React部分及React組件的相關(guān)操作,具有內(nèi)容詳情跟隨小編一起看看吧2021-08-08