【问题标题】:React Native - updating state between navigation screen componentsReact Native - 在导航屏幕组件之间更新状态
【发布时间】:2020-03-07 03:10:10
【问题描述】:

我是 React Native 的新手,遇到了一个我似乎无法克服的问题,尽管表面上看起来很简单。我正在开发一个利用 Google API 位置服务和反应导航的应用程序。

我有两个组件在 stackNavigator 中分​​组。组件 A 保存一个位置状态,我希望组件 B(这是一个利用异步 API 调用的地理位置选择器屏幕)根据用户选择生成位置数据,并将此数据推送到组件 A 并更新其状态。

我的问题在于更新组件 A 的状态,因为从 B 返回的对象是未定义的。

希望有好心人能帮忙!

//COMPONENT A
    const [location, setLocation] = useState({})
    useFocusEffect(useCallback(
        () => {
                const getNewLocation = () => {
                    const location = {
                        name: props.navigation.getParam('name'),
                        latitude: props.navigation.getParam('latitude'),
                        longitude: props.navigation.getParam('longitude')
                    }
                    return location
                }
                setLocation(getNewLocation())

        }, []
    ))
    return (
        <ScrollView style={style.homeContainer}>{location.name}</ScrollView>
    )


//COMPONENT B
    const handleLocationSelect = async (text) => {
        const coordsObject = await getCoordsFromString(text)
        const {results: [{geometry: {location: {lat: latitude, lng: longitude}}}]} = coordsObject
        props.navigation.navigate('Home',
            {
                name: text,
                latitude: latitude,
                longitude: longitude
            }    
        )
    }

    return (
        <ScrollView style={style.container}>
            <Text style={style.header}>Choose a location - more coming soon!</Text>
            <TouchableOpacity
                onPress={() => handleLocationSelect('Brighton, UK')}>
                <Text style={style.location}>Brighton</Text>
            </TouchableOpacity>
.......................................
.......................................
        </ScrollView>

【问题讨论】:

    标签: javascript reactjs react-native react-navigation


    【解决方案1】:

    您没有提到组件 A 是否有路由“Home”,所以我认为它有。为了获取导航道具,可以使用“首页”中的useNavigation()钩子,即

    const nav = useNavigation();
    const location = nav.getParam("location");
    

    我不确定你为什么需要 useFocusEffect 和 useCallback,它们对于长时间运行的操作相当有用,而你似乎只是同步传递参数。

    如果您的导航树越来越大,您可能需要考虑使用 Redux 来保持中心状态。

    【讨论】:

    • 组件 A 实际上是主屏幕,它确实有导航道具 :) 我正在使用 useFocusEffect 因为它是我可以弄清楚如何更改某些文本的唯一方法(源自更新的状态) 当我从组件 B 导航回此屏幕时。希望我有意义..
    • 如果它确实有导航道具,有什么问题?为了清楚起见,当你使用navigation.navigate()时,你并没有真正向后移动,你是在添加一个新屏幕到堆栈。
    • 在组件 A 中,属性返回未定义,但是当我 console.log B 中的所有内容时,属性被正确填充。我不确定这是否与我的事实有关m 从 B 进行异步调用