React Native自定义useLocationPicker Hook重渲染异常求助
问题修复方案
问题根源
每次调用setQuery修改搜索关键词时,useLocationPicker Hook会因状态更新重新执行,导致内部定义的LocationPickerModal函数组件被重新创建。React会将旧的Modal组件卸载后重新挂载,直观表现就是模态框先关闭再重新打开。
修复步骤
1. 用useCallback稳定内部函数
将所有事件处理函数用useCallback包裹,避免每次Hook重渲染时生成新的函数实例,减少不必要的组件更新:
import { useState, useMemo, useCallback } from 'react'; const useLocationPicker = ({ handleSelect }) => { const [modalVisible, setModalVisible] = useState(false); const [query, setQuery] = useState('') const handleOpenLocationPicker = useCallback(async () => { setModalVisible(true) }, []); const handleCloseLocationPicker = useCallback(async () => { setModalVisible(false) setQuery(''); }, []); const handleSearch = useCallback(async (text) => { setQuery(text); }, []); const handleGetCurrentLocation = useCallback(async () => { const CURRENT_LOCATION = await getCurrentLocation() handleSelect(CURRENT_LOCATION) handleCloseLocationPicker(); }, [handleSelect, handleCloseLocationPicker]); const handleSelectLocation = useCallback(async (data) => { handleSelect(data) handleCloseLocationPicker(); }, [handleSelect, handleCloseLocationPicker]);
2. 用useMemo缓存Modal组件
把LocationPickerModal用useMemo包裹,指定明确的依赖项,确保只有依赖变化时才重新创建组件:
const LocationPickerModal = useMemo(() => () => ( <Modal animationType="slide" presentationStyle='formSheet' visible={modalVisible} onRequestClose={handleCloseLocationPicker} > <View> <TextInput onChangeText={(text)=>handleSearch(text)} placeholder='Search' style={styles.searchBox} /> </View> {query.length===0? <> <TouchableOpacity style={styles.item} onPress={handleGetCurrentLocation} > <View style={styles.itemIcon} /> <Text style={styles.p1}>Your location</Text> </TouchableOpacity> <History handleSelect={handleSelectLocation} /> </> : <Predictions query={query} handleSelect={handleSelectLocation} /> } </Modal> ), [modalVisible, query, handleCloseLocationPicker, handleSearch, handleGetCurrentLocation, handleSelectLocation]); return { handleOpenLocationPicker, LocationPickerModal }; } export default useLocationPicker
原理说明
useCallback通过缓存函数实例,保证依赖不变时函数引用不会改变,避免子组件因函数引用变化触发无意义重渲染。useMemo缓存了LocationPickerModal的组件定义,确保只有指定的核心依赖(如模态框可见状态、搜索关键词)变化时,才会重新生成组件,彻底解决Modal被频繁卸载和挂载的问题。
内容的提问来源于stack exchange,提问作者Harvsystem
相关产品推荐
相关产品推荐

