You need to enable JavaScript to run this app. React Native如何在ScreenTwo中正常显示ScreenOne更新后的points变量
优惠活动
大模型
产品
解决方案
定价
更多

React Native如何在ScreenTwo中正常显示ScreenOne更新后的points变量

问题根因

你当前的实现无法拿到更新后的值,核心有两个问题:

  • ScreenOne组件内部定义的valuePoints是函数作用域内的普通变量,每次组件渲染都会被重新初始化为0。你导出时是把初始值0赋值给了module.exports.valuePoints,后续对局部变量valuePoints的修改不会同步到导出的对象上,所以ScreenTwo拿到的永远是初始值0。
  • 你尝试用localStorage拿不到值,大概率是要么存的时机不对(分数更新后没有主动调用存的方法),要么React Native环境下误用了浏览器端的localStorage(React Native本身没有localStorage API,需要用专门的AsyncStorage库)。
最优实现方案

根据你的使用场景,推荐优先选以下两种方案:

方案1:路由参数传递(适用从ScreenOne直接跳转到ScreenTwo的场景)

这是最轻量的方案,无需额外引入依赖,直接用React Navigation自带的路由传参能力即可。

ScreenOne改造代码

import { useState } from 'react'
const ScreenOne = ({ navigation }) => {
    // 用useState托管分数,保证更新时组件可正常重渲染
    const [valuePoints, setValuePoints] = useState(0)

    // 校验逻辑计算最终分数
    let calculatedPoints = 0
    if (userInput1.search('No') < 0) {
        console.log('Wrong answer!')
    } else {
        calculatedPoints += 10
    }

    if (userInput2.search('Yes') < 0) {
        console.log('Wrong answer!')
    } else {
        calculatedPoints += 10
    }
    // 同步更新state
    setValuePoints(calculatedPoints)

    // 跳转ScreenTwo时携带分数参数
    const jumpToScreenTwo = () => {
        navigation.navigate('ScreenTwo', {
            points: valuePoints
        })
    }

    return (
        <ScreenContainer>
            <ScrollView style={{ flex: 1, width: '100%' }}>
                <PointsAmount>
                    {valuePoints}
                </PointsAmount>
                {/* 跳转按钮示例,你可以替换为你自己的触发跳转的逻辑 */}
                <TouchableOpacity onPress={jumpToScreenTwo}>
                    <Text>前往第二页</Text>
                </TouchableOpacity>
            </ScrollView>
        </ScreenContainer>
    )
}

export default ScreenOne;

ScreenTwo改造代码

const ScreenTwo = ({ route, navigation }) => {
    // 从路由参数中获取分数,默认值设为0避免参数为空报错
    const valuePoints = route.params?.points ?? 0

    return (
        <PointsContainer>
            <ScrollView style={{flex:1, width: '100%'}}>
            <TouchableOpacity onPress={() => navigation.navigate('MyTabs1')} >
                <ScoreCard header='Points gained' points={valuePoints} goal={100} />
            </TouchableOpacity>
            </ScrollView>
        </PointsContainer>
    )
}

export default ScreenTwo;

方案2:Context全局状态管理(适用多页面共享分数、非直接跳转的场景)

如果两个页面不是直接跳转的关系(比如是同级Tab页、多个页面都要用到分数),用React自带的Context API实现全局状态共享即可,无需引入Redux等重状态管理库。

第一步:新建全局状态文件PointsContext.js

import { createContext, useContext, useState } from 'react'

const PointsContext = createContext()

// 全局状态Provider,需要包裹在你的根组件外层
export const PointsProvider = ({ children }) => {
    const [points, setPoints] = useState(0)
    return (
        <PointsContext.Provider value={{ points, setPoints }}>
            {children}
        </PointsContext.Provider>
    )
}

// 自定义hooks,方便组件直接调用全局状态
export const usePoints = () => useContext(PointsContext)

第二步:根组件引入Provider

修改你的App.js入口文件,把整个应用包裹在PointsProvider里:

import { PointsProvider } from './PointsContext'
import { NavigationContainer } from '@react-navigation/native'

export default function App() {
    return (
        <PointsProvider>
            <NavigationContainer>
                {/* 替换为你自己的路由配置 */}
            </NavigationContainer>
        </PointsProvider>
    )
}

第三步:ScreenOne中使用全局状态

import { usePoints } from './PointsContext'

const ScreenOne = ({ navigation }) => {
    const { points, setPoints } = usePoints()

    // 校验逻辑计算完分数后更新全局状态
    let calculatedPoints = 0
    if (userInput1.search('No') < 0) {
        console.log('Wrong answer!')
    } else {
        calculatedPoints += 10
    }
    if (userInput2.search('Yes') < 0) {
        console.log('Wrong answer!')
    } else {
        calculatedPoints += 10
    }
    setPoints(calculatedPoints)

    return (
        <ScreenContainer>
            <ScrollView style={{ flex: 1, width: '100%' }}>
                <PointsAmount>
                    {points}
                </PointsAmount>
            </ScrollView>
        </ScreenContainer>
    )
}

export default ScreenOne;

第四步:ScreenTwo中直接读取全局状态

import { usePoints } from './PointsContext'

const ScreenTwo = ({ navigation }) => {
    const { points } = usePoints()

    return (
        <PointsContainer>
            <ScrollView style={{flex:1, width: '100%'}}>
            <TouchableOpacity onPress={() => navigation.navigate('MyTabs1')} >
                <ScoreCard header='Points gained' points={points} goal={100} />
            </TouchableOpacity>
            </ScrollView>
        </PointsContainer>
    )
}

export default ScreenTwo;

持久化补充说明

如果需要退出应用再打开还保留分数,你可以安装@react-native-async-storage/async-storage库,在分数更新后调用AsyncStorage.setItem('user_points', String(points))存储,应用启动时读取后同步到全局状态即可。

内容的提问来源于stack exchange,提问作者edwin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 22:45:04