返回屏幕时在 React Native 中不调用 useEffect
useEffect not called in React Native when back to screen
你好吗。
这是这个问题的场景。
假设有 2 个屏幕以使其简单。
- 进入A画面。 useEffect of A screen called.
- 从A屏导航到B屏
从 B 导航回 A 屏幕。
此时并没有调用useEffect
function CompanyComponent(props) {
const [roleID, setRoleID] = useState(props.user.SELECTED_ROLE.id)
useEffect(()=>{
// this called only once when A screen(this component) loaded,
// but when comeback to this screen, it doesn't called
setRoleID(props.user.SELECTED_ROLE.id)
}, [props.user])
}
所以当再次回到A画面时,A画面的更新状态保持不变(不是从道具加载)
我不会在屏幕 B 中更改 props.user。
但我认为const [roleID, setRoleID] = useState(props.user.SELECTED_ROLE.id)
这一行至少应该被调用。
我正在使用 redux-persist。我认为这不是问题。
对于导航,我使用这个
// to go first screen A, screen B
function navigate(routeName, params) {
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params,
})
);
}
// when come back to screen A from B
function goBack() {
_navigator.dispatch(
NavigationActions.back()
);
}
屏幕出现时有什么回调可以使用吗?
我的代码有什么问题?
谢谢
当您从 A 导航到 B 时,组件 A 不会被销毁(它保留在导航堆栈中)。因此,当您向后导航时,代码不会再次 运行。
也许是一种更好的方法来实现您想要使用导航生命周期事件的目的(我假设您正在使用 react-navigation
)即订阅 didFocus
事件和 运行 每当组件聚焦时你想要的任何代码例如
const unsubscribe = props.navigation.addListener('didFocus', () => {
console.log('focussed');
});
不要忘记在适当的时候取消订阅,例如
// sometime later perhaps when the component is unmounted call the function returned from addListener. In this case it was called unsubscribe
unsubscribe();
以下解决方案对我有用:
import React, { useEffect } from "react";
import { useIsFocused } from "@react-navigation/native";
const ExampleScreen = (props) => {
const isFocused = useIsFocused();
useEffect(() => {
console.log("called");
// Call only when screen open or when back on screen
if(isFocused){
getInitialData();
}
}, [props, isFocused]);
const getInitialData = async () => {}
return (
......
......
)
}
我用过react navigation 5+
@react-navigation/native": "5.6.1"
当前版本的 React Navigation 提供了 useFocusEffect hook。参见 here。
React Navigation 5 提供了一个 useFocusEffect 钩子,类似于 useEffect,唯一的区别是它仅在屏幕当前获得焦点时运行。查看文档 https://reactnavigation.org/docs/use-focus-effect
useFocusEffect(
useCallback(() => {
const unsubscribe = setRoleID(props.user.SELECTED_ROLE.id)
return () => unsubscribe()
}, [props.user])
)
import { useIsFocused } from "@react-navigation/native";
const focus = useIsFocused(); // use if focus as shown
useEffect(() => { // whenever you are in the current screen, it will be true vice versa
handleGetProfile();
}, [focus]);
你好吗。 这是这个问题的场景。 假设有 2 个屏幕以使其简单。
- 进入A画面。 useEffect of A screen called.
- 从A屏导航到B屏
从 B 导航回 A 屏幕。 此时并没有调用useEffect
function CompanyComponent(props) { const [roleID, setRoleID] = useState(props.user.SELECTED_ROLE.id) useEffect(()=>{ // this called only once when A screen(this component) loaded, // but when comeback to this screen, it doesn't called setRoleID(props.user.SELECTED_ROLE.id) }, [props.user]) }
所以当再次回到A画面时,A画面的更新状态保持不变(不是从道具加载)
我不会在屏幕 B 中更改 props.user。
但我认为const [roleID, setRoleID] = useState(props.user.SELECTED_ROLE.id)
这一行至少应该被调用。
我正在使用 redux-persist。我认为这不是问题。 对于导航,我使用这个
// to go first screen A, screen B
function navigate(routeName, params) {
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params,
})
);
}
// when come back to screen A from B
function goBack() {
_navigator.dispatch(
NavigationActions.back()
);
}
屏幕出现时有什么回调可以使用吗? 我的代码有什么问题?
谢谢
当您从 A 导航到 B 时,组件 A 不会被销毁(它保留在导航堆栈中)。因此,当您向后导航时,代码不会再次 运行。
也许是一种更好的方法来实现您想要使用导航生命周期事件的目的(我假设您正在使用 react-navigation
)即订阅 didFocus
事件和 运行 每当组件聚焦时你想要的任何代码例如
const unsubscribe = props.navigation.addListener('didFocus', () => {
console.log('focussed');
});
不要忘记在适当的时候取消订阅,例如
// sometime later perhaps when the component is unmounted call the function returned from addListener. In this case it was called unsubscribe
unsubscribe();
以下解决方案对我有用:
import React, { useEffect } from "react";
import { useIsFocused } from "@react-navigation/native";
const ExampleScreen = (props) => {
const isFocused = useIsFocused();
useEffect(() => {
console.log("called");
// Call only when screen open or when back on screen
if(isFocused){
getInitialData();
}
}, [props, isFocused]);
const getInitialData = async () => {}
return (
......
......
)
}
我用过react navigation 5+
@react-navigation/native": "5.6.1"
当前版本的 React Navigation 提供了 useFocusEffect hook。参见 here。
React Navigation 5 提供了一个 useFocusEffect 钩子,类似于 useEffect,唯一的区别是它仅在屏幕当前获得焦点时运行。查看文档 https://reactnavigation.org/docs/use-focus-effect
useFocusEffect(
useCallback(() => {
const unsubscribe = setRoleID(props.user.SELECTED_ROLE.id)
return () => unsubscribe()
}, [props.user])
)
import { useIsFocused } from "@react-navigation/native";
const focus = useIsFocused(); // use if focus as shown
useEffect(() => { // whenever you are in the current screen, it will be true vice versa
handleGetProfile();
}, [focus]);