Перерисовать компонент при навигации по стеку с помощью React Navigation

Я сейчас пользуюсь react-navigation делать стековую и табулированную навигацию.

Можно ли повторно визуализировать компонент каждый раз, когда пользователь переходит на определенные экраны? Я хочу убедиться, что перезапустить componentDidMount() каждый раз, когда достигается определенный экран, я получаю последние данные с сервера, вызывая соответствующего создателя действий.

На какие стратегии я должен смотреть? Я уверен, что это обычный шаблон проектирования, но я не смог увидеть документированные примеры.

7 ответов

Решение

События жизненного цикла React Navigation, указанные в реагирующей навигации

React Navigation генерирует события для отображения компонентов, которые на них подписываются. Вы можете подписаться на четыре различных события: willFocus, willBlur, didFocus и didBlur. Подробнее о них читайте в справочнике по API.


Давай проверим это,

С помощью слушателей навигации вы можете добавить список событий на свою страницу и вызывать функцию каждый раз, когда ваша страница будет сфокусирована.

const didBlurSubscription = this.props.navigation.addListener(
  'willBlue',
  payload => {
    console.debug('didBlur', payload);
  }
);

// Remove the listener when you are done
didBlurSubscription.remove();

Замените функцию полезной нагрузки и измените ее на функцию "обновления".

Надеюсь, это поможет.

Если вы используете React Navigation 5.X, просто сделайте следующее:

import { useIsFocused } from '@react-navigation/native'

export default function App(){

const isFocused = useIsFocused()

    useEffect(() => {
        //Update the state you want to be updated
    } , [isFocused])
}

Вы также можете использовать хук useFocusEffect, тогда он будет перерисовываться каждый раз, когда вы переходите на экран, где вы используете этот хук.

      useFocusEffect(()=> {
    your code
})

По просьбе Дмитрия в его комментарии я покажу вам, как вы можете принудительно выполнить повторный рендеринг компонента, потому что сообщение оставляет нам эту двусмысленность.

Если вы ищете, как принудительно выполнить повторный рендеринг вашего компонента, просто обновите какое-либо состояние (любое из них), это вызовет повторный рендеринг компонента. Я советую вам создать состояние контроллера, то есть, когда вы хотите принудительно выполнить рендеринг, просто обновите это состояние случайным значением, отличным от предыдущего.

Добавить useEffectхук с параметрами совпадения, на которые вы хотите отреагировать. Обязательно используйте параметры, которые управляют вашим компонентом, чтобы он выполнял повторную визуализацию. Пример:

      export default function Project(props) {
    const [id, setId] = useState(props?.match?.params?.id);
    const [project, setProject] = useState(props?.match?.params?.project);

    useEffect(() => {
        if (props.match) {
            setId(props.match?.params.id);
            setProject(props.match?.params.project);
        }
    }, [props.match?.params]);
   
......

Этот работает нормально: мы слушаем событие фокуса, которое срабатывает каждый раз, когда печатается текущий экран. В этом случае мы вызываем прикрепленную функцию обратного вызова, которая определяет, что мы хотим сделать. И не забудьте удалить прослушиватель событий, когда закончите.

      import { useNavigation } from "@react-navigation/native";
const navigation = useNavigation();
useEffect(() => {
  const didFocus = navigation.addListener(
    'focus',
    () => {
      yourFunctionToCall();
    }
  );
  
  // Remove the listener when you are done
  return didFocus;
}, [navigation]
);

Для запуска рендеринга при переходе на экран.

      import { useCallback } from "react"; 
import { useFocusEffect } from "@react-navigation/native";  

// Quick little re-render hook       
function useForceRender() {
    const [value, setValue] = useState(0);
    return [() => setValue(value + 1)];
}

export default function Screen3({ navigation }) {
  const [forceRender] = useForceRender();

  // Trigger re-render hook when screen is focused
  // ref: https://reactnavigation.org/docs/use-focus-effect
  useFocusEffect(useCallback(() => { 
    console.log("NAVIGATED TO SCREEN3")
    forceRender();
  }, []));
}

Примечание:

      "@react-navigation/native": "6.0.13",
"@react-navigation/native-stack": "6.9.0",
Другие вопросы по тегам