gpt4 book ai didi

reactjs - React (Native) Context API 导致 Stack Navigator (React Navigation 5) 在状态更新后重新渲染

转载 作者:行者123 更新时间:2023-12-03 23:05:09 24 4
gpt4 key购买 nike

提前感谢您帮助解决这个问题。

一些上下文(无双关语)
我正在从事一个公司的项目,该项目将限制我将所有代码都放在这里,但我会尝试在不泄露国家 secret 的情况下尽可能多地放置相关代码。
基本上,React Native 应用程序使用的是 React Navigation v5,我已经尝试解决这个问题两天了。我明白发生了什么,但我不明白为什么会发生或如何解决它。
在应用程序代码中的某处,您有以下代码。

export const Lounge = function Lounge(props: {navigation: any}) {

const {navigation: {setOptions}} = props
const bottomTabBarCtx = useContext(BottomTabBarContext)

// const [routeName, setRouteName] = useState("LoungeList")

useEffect(() => {
setOptions({tabBarVisible: bottomTabBarCtx.isVisible})
}, [bottomTabBarCtx.isVisible, setOptions])

return <Stack.Navigator initialRouteName={"LoungeList"}>
<Stack.Screen
name="LoungeList"
component={List}
options={{headerShown: false}}
/>

<Stack.Screen
name="LoungeDetails"
component={Details}
options={{
headerLeft : buttonProps => <BackButton {...buttonProps} />,
headerRight: buttonProps => <LoungeHeaderRightDetailsButton {...buttonProps} />,
headerTitle: 'Lounge Details',
}}
/>

<Stack.Screen
name="LoungeParticipants"
component={Participants}

options={{
headerLeft : buttonProps => <BackButton {...buttonProps} />,
headerRight: buttonProps => <LoungeHeaderRightDetailsButton {...buttonProps} />,
headerTitle: 'Lounge Participants',
}}
/>

<Stack.Screen
name="LoungeAdd"
component={LoungeEdit}

options={{
headerLeft : buttonProps => <BackButton {...buttonProps} />,
headerTitle: 'Create Lounge',
}}
/>

<Stack.Screen
name="LoungeEdit"
component={LoungeEdit}

options={{
headerLeft : buttonProps => <BackButton {...buttonProps} />,
headerTitle: 'Edit Lounge',
}}
/>

...
上面的文件只是定义了可以在应用程序的这一部分中导航到的路由。
初始屏幕/路线名称 = '休息室列表'
这一切正常。
来自 LoungeList 屏幕,我点击休息室摘要单元格(请发挥您的想象力),然后点击将我带到下面的屏幕: 贵宾室详情
贵宾室详情屏幕上,我看到了休息室的详细信息,在那个屏幕上,还有一个加入按钮。此按钮使我能够加入休息室。
功能应该是,当用户点击加入按钮时,按钮进入加载状态,当它完成加载时,它应该显示 已加入 .这是应该发生的 但是 发生这种情况后立即 我被导航到 LoungeList 屏幕
以下是我为加入休息室而执行的代码:
const userDidJoinLounge = (joinedLounge: LoungeWithUsers) => {

if(joinedLounge){

console.log("joinedLounge before update == ", joinedLounge);

const allLoungesNew = LoungeController.replaceLoungeInLoungeArray(
userCtx.allLoungesList,
joinedLounge
);

const userLoungesNew = LoungeController.getUserJoinedLoungeArrayListOnJoin(
allLoungesNew,
userCtx.userLoungeList,
joinedLounge
);

console.log("allLounges after update == ", allLoungesNew);
console.log("joinedLounges after update == ", userLoungesNew);

userCtx.updateLoungeLists(allLoungesNew, userLoungesNew)

}
}
在上面的函数中,行 userCtx.updateLoungeLists(allLoungesNew, userLoungesNew)接受两个参数,应用程序上所有休息室的列表,以及用户加入的休息室列表。此函数更新保存这两个值的上下文。

大问题
问题 :我一直被重定向到 LoungeList 屏幕,即使没有任何代码指示应用程序执行此操作。
可能有帮助的事情
我玩过很多东西,一些可以帮助你弄清楚发生了什么的事情是:
  • 似乎正在重新渲染 React Navigation 路由配置。我这样说是因为当我将 initialRouteName 更改为 时贵宾室详情 ,休息室详细信息屏幕(加入按钮所在的位置)闪烁,但它停留在同一个屏幕上 .这也告诉我,在该函数结束时,堆栈导航器回退到任何 初始路由名称 是。
  • 奇怪的是,当我只设置 allLoungesNew然后应用程序不会导航到 initialRouteName ,看来这个问题只有在我设置 userLoungesNew 时才会发生在 userContext 的状态中。

  • 当用户点击加入按钮时,如何阻止 react 导航离开屏幕?
    非常感谢您的帮助。我希望我已经给了你足够的信息来解决这个问题。请随时提出更多问题以帮助解决问题。我会告诉你我可以做什么。

    最佳答案

    在互联网上搜索了大约 3 天的答案后,答案非常简单。
    我找到了很多文章和建议,告诉我不要为 放置任何代码。正在创建 组件内部的导航器。
    我没有为这个应用程序编写原始代码,我是在大约 2 个月前加入的 ,虽然我看过嵌套的导航器,但我并没有立即意识到问题可能在导航链/堆栈的更高层。
    在根index.tsx文件中,前开发人员将根导航器(包含所有其他子/嵌套导航器的导航器)放在入口点组件中。
    这个文件是组件中唯一可以创建导航器的地方,但我没想到那里看,因为 该行为似乎仅限于应用程序的休息室部分
    解决方案
    无论如何,修复很简单。在根index.tsx文件中,我将每个导航器声明从(根)功能组件中移出,从而解决了问题。
    很明显,每当我在我的 UserContext 中调用状态更改时,导航器都会被取消/重新安装,现在这是有道理的,因为创建导航器的代码在组件内部,每当我更改状态时,导航器也会被重新渲染,这让我回到了 initialRouteName屏幕。
    主要经验教训
    React Navigation v5 与其早期版本不同,现在允许我们使用 JSX 标签声明导航器,这为我们提供了更多的灵活性,为我们的导航器提供了动态配置之类的机会,但是我们必须小心 我们的任何/所有导航器都被声明为
    在这个问题上 3 天后,一切都指向了这个解决方案,但我不认为我正在处理的代码是这种情况,因为除了 一个文件 ,所有其他导航器声明都是在组件之外进行的。
    对你来说可能是一样的。 如果您在状态更改时遇到这种行为,那么问题导航器可能位于您的导航器链的上端 .
    我希望这可以帮助别人! 😊

    关于reactjs - React (Native) Context API 导致 Stack Navigator (React Navigation 5) 在状态更新后重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63196685/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com