You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 20:24:53