Перерисовать компонент при навигации по стеку с помощью 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",