Solito项目中实现跨平台useIsFocused钩子的最佳实践
solito 🧍♂️ React Native + Next.js, unified. 项目地址: https://gitcode.com/gh_mirrors/so/solito
背景介绍
在React Native应用中,useIsFocused
是一个常用的钩子函数,用于判断当前屏幕是否处于聚焦状态。然而在Web环境中,这个钩子并不适用。Solito作为一个优秀的跨平台解决方案,需要处理这种平台差异性问题。
基础实现方案
Native端实现
对于Native端,我们可以直接使用React Navigation提供的原生实现:
export { useIsFocused } from '@react-navigation/native'
Web端实现
在Web环境中,由于页面总是处于"聚焦"状态,我们可以简化实现:
export function useIsFocused() {
return true
}
这种实现方式简单直接,适用于大多数Web场景。
高级场景:处理模态框情况
当应用中存在模态框时,情况会变得复杂。我们需要考虑模态框覆盖主屏幕时的聚焦状态判断。
创建模态框上下文
首先,我们需要建立一个上下文来判断组件是否位于模态框中:
import { createContext } from 'react'
export const ModalScreenContext = createContext(false)
在页面中使用上下文
在Next.js页面中,我们可以这样使用上下文:
import { ModalScreenContext } from 'context/modal-screen'
import { useRouter } from 'next/router'
export default function ArtistPage() {
const router = useRouter()
return (
<>
<ArtistScreen />
<ModalScreenContext.Provider value={true}>
{!!router?.query?.showsEditModal && <EditArtistModal />}
</ModalScreenContext.Provider>
</>
)
}
增强版useIsFocused实现
结合路由信息和上下文,我们可以实现更精确的聚焦判断:
import { useContext } from 'react'
import { useRouter } from 'next/router'
import { ModalScreenContext } from './context/modal-screen'
export function useIsFocused() {
const { query } = useRouter()
const iAmAModal = useContext(ModalScreenContext)
if (iAmAModal) {
return true
}
const isThereAModalVisibleOnTopOfMe =
Object.keys(query ?? {}).some((key) => key.toLowerCase().includes('modal'))
return !isThereAModalVisibleOnTopOfMe
}
路由导航实现
为了保持一致性,建议在URL查询参数中使用"modal"关键字来标识模态框状态:
<Link href="/artists/drake" query={{ showsEditModal: true }} />
更高级的实现可以结合as
属性,使URL更加友好:
<Link href="/artists/drake" as="/@drake/edit" query={{ showsEditModal: true }} shallow />
最佳实践建议
- 命名规范:统一使用"modal"关键字作为查询参数的标识
- 上下文隔离:确保模态框内容与主屏幕内容通过上下文明确区分
- 浅路由:使用shallow路由避免不必要的页面刷新
- 状态一致性:确保Native和Web端的聚焦状态逻辑保持一致
总结
通过Solito的跨平台能力,我们可以优雅地处理useIsFocused
在不同环境下的实现差异。基础场景下使用简单的布尔值返回,复杂场景下结合路由和上下文实现精确控制。这种模式不仅适用于聚焦状态判断,也可以扩展到其他需要平台差异化处理的场景中。
solito 🧍♂️ React Native + Next.js, unified. 项目地址: https://gitcode.com/gh_mirrors/so/solito
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考