it-source

화면으로 돌아가면 React Native에서 useEffect가 호출되지 않음

criticalcode 2023. 3. 17. 21:41
반응형

화면으로 돌아가면 React Native에서 useEffect가 호출되지 않음

잘 지내시나요.이것은 이 문제의 시나리오입니다.간단하게 하기 위해 화면이 2개 있다고 칩시다.

  1. A 화면으로 들어갑니다.A 화면의 useEffect 호출.
  2. A 화면에서 B 화면으로 이동하다
  3. 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의 사용자 소품을 변경하는 것이 아닙니다.하지만 내 생각엔…const [roleID, setRoleID] = useState(props.user.SELECTED_ROLE.id)이 회선은 적어도 호출되어야 합니다.

레독스 퍼시스트를 사용하고 있습니다.이것은 문제가 되지 않는다고 생각합니다.내비게이션을 위해 나는 이것을 사용한다.

// 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()
    );
}

화면이 뜨면 사용할 수 있는 콜백이 있나요?내 코드에 무슨 문제가 있나요?

감사해요.

이하의 솔루션이 유효했습니다.

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 (
        ......
        ......
    )
}

리액션 네비게이션 5+ 사용

@http-navigation/http: "5.6.1"

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();

반응 탐색의 현재 버전은 useFocusEffect 후크를 제공합니다.여기 보세요.

React Navigation 5는 useFocusEffect 후크를 제공하며 useEffect와 유사하며 유일한 차이점은 화면이 현재 포커스를 맞추고 있을 때만 실행된다는 것입니다.매뉴얼은http://https://reactnavigation.org/docs/use-focus-effect 를 참조해 주세요.

 useFocusEffect(
    useCallback(() => {
      const unsubscribe = setRoleID(props.user.SELECTED_ROLE.id)
      return () => unsubscribe()
    }, [props.user])
  )

위에서 설명한 솔루션은 확실히 기능합니다만, 어떠한 경우에도, 왜 여기서 문제가 발생하는지를 알 필요가 있습니다.

리액트 네이티브에서는 모든 화면이 스택되어 있으며, 이는 LAST-IN-FIRST-OUT 순서를 따르기 때문에 화면 A에 있을 때 진행됩니다.Back()은 스택에 마지막으로 추가된 화면이기 때문에 컴포넌트(스크린 A)가 마운트 해제되지만 SCREEN B로 이동해도 마운트 해제되지 않고 다음 SCREEN B가 스택에 추가됩니다.

그러니 이제, 네가 갈 때.스크린 A로 되돌아가()는 마운트 해제되지 않았기 때문에 useEffect는 실행되지 않습니다.리액트 네이티브는 내비게이션을 이 방식으로 유지하여 반응성과 실시간성을 높입니다.

다른 화면으로 이동할 때마다 화면 마운트를 해제하려면 navigation.navigation이 아닌 navigation.replace를 시도할 수 있습니다.

도움이 되시길 바랍니다.

import { useIsFocused } from "@react-navigation/native"; 
 
const focus = useIsFocused();  // useIsFocused as shown          
 
useEffect(() => {   // whenever you are in the current screen, it will be true vice versa
    if(focus == true){ // if condition required here because it will call the function even when you are not focused in the screen as well, because we passed it as a dependencies to useEffect hook
       handleGetProfile();
    }
}, [focus]);

루션을 사용한 useEffect

import { useNavigation } from '@react-navigation/native';

const Component = (props) => {
  const navigation = useNavigation()
  const isFocused = useMemo(() => navigation.isFocused(), [])
  useEffect(() => {
    if (isFocused) {
      // place your logic
    }
  }, [isFocused])
}

언급URL : https://stackoverflow.com/questions/60182942/useeffect-not-called-in-react-native-when-back-to-screen

반응형