Ric*_*wis 7 navigation react-native react-navigation-v6
我有一个屏幕,可以调用 api 来获取一些数据,然后显示
我看到的一个问题是,当我离开屏幕(我使用的是react-navigation 6.x)然后返回时,它useEffect()不会被调用
从我到目前为止所读到的内容来看,这取决于userId不改变的价值(我想我需要围绕这个问题做更多阅读useEffect()才能更好地理解,也许有人会帮助解决这个问题)
import React, {useState, useEffect, useContext} from 'react';
import AppContext from '../../components/AppContext.js';
export const CreateNewEvent = () => {
const globalContext = useContext(AppContext);
const userId = globalContext.userInfo.id;
useEffect(() => {
const body = JSON.stringify({userId});
fetch(eventTypesUrl, {
method: 'POST',
headers: {'Content-Type': 'application/json', Accept: 'application/json'},
body: body,
})
.then(response => response.json())
.then(json => setEventTypeData(json))
.catch(error => console.error(error))
.finally(() => setLoading(false));
}, [userId]);
}
Run Code Online (Sandbox Code Playgroud)
所以在我的场景中,我位于屏幕 1(在这里我可以创建一个事件,该事件发出请求以获取所有事件类型并将它们加载到选择菜单中)
当我导航到屏幕 2(以创建事件类型)然后返回屏幕 1 时,useEffect()不会调用挂钩,导致无法看到我刚刚创建的事件类型(希望这是有意义的)。还请注意,任何先前在屏幕 1 中输入的数据仍然保留
我遇到了这篇文章,这似乎是我正在处理的问题,只是有点不确定如何使用我的设置来实现
如何确保当我返回时屏幕 2 进行 api 调用并且所有以前的表单数据都被清除?
谢谢
Fis*_*uel 10
从本质上讲,当用户导航回该屏幕时,React Navigation 不会重新渲染屏幕以优化性能,并避免不必要的重新渲染。
当需要时,它们提供了一个有用的钩子来检测屏幕何时聚焦并运行一些副作用。
让重构代码如下:
Top-level import
import { useFocusEffect } from "@react-navigation/core";
// Run side effects when screen focused, navigated, or visited
useFocusEffect(
React.useCallback(() => {
const body = JSON.stringify({ userId });
fetch(eventTypesUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: body,
})
.then(response => response.json())
.then(json => setEventTypeData(json))
.catch(error => console.error(error))
.finally(() => setLoading(false));
return () => {
// Run somelogisx when user leave screen,
// Cleaning caches or cancelling subscriptions
};
}, [userId]),
);
Run Code Online (Sandbox Code Playgroud)
注: React.useCallback是 API 的一部分useFocusEffect。React Navigation 团队尝试通过记忆来优化屏幕性能。
在 React Native 中,当您向前导航时,每个屏幕都会被推送到导航堆栈。
现在,当您向后导航时,会弹出上一个屏幕,并显示堆栈中最上面的屏幕。由于最上面的屏幕中没有任何内容(状态或道具)发生变化,因此不会重新渲染。
所以你必须做一些手工工作。
import { useIsFocused } from "@react-navigation/native";
const isFocused = useIsFocused();
Run Code Online (Sandbox Code Playgroud)
isFocused 是布尔值
useEffect(() => {
if (userId && isFocused) {
// Code which you want to execute when screen is loaded first
// time(and after userId is initialised) or loaded after press of
// back button
}
}, [userId, isFocused]);
Run Code Online (Sandbox Code Playgroud)