我有一个通过状态对象触发的组件:
const Alerts = () => {
const alert = useStore((state) => state.alert);
const setAlert = useStore((state) => state.setAlert);
const alertsModalRef = useRef(null);
useEffect(() => {
console.log("TRIGGER");
if (alert) {
alertsModalRef.current?.present();
}
}, [alert]);
...
我通过从不同屏幕上的另一个组件单击按钮来触发它。例如:
export function UpdateSomething() {
const setAlert = useStore((state) => state.setAlert);
return (
<View>
<Button
title="Continue"
onPress={() => {
setAlert("something");
}}
/>
</View>
);
}
当我加载我的应用程序并点击触发按钮时,我看到“TRIGGER”被打印到控制台一次。但是,当我转到另一个屏幕并点击另一个按钮时,甚至当我返回第一个屏幕并再次点击同一个按钮时,它会打印“TRIGGER”三遍。
我怀疑我需要向 useEffect
添加某种清理方法 - 但如果是这样,那里需要什么清理?
如果不是这样呢?这是怎么回事?
抱歉,我意识到这可能已经以各种形式被问过一百万次了。我阅读了文档和许多帖子,但仍然很困惑。
正如 Drew 推荐的那样,我测试并看到每当我访问我的应用程序中使用 React Navigation 的屏幕时,都会重新安装 Alerts
组件。
我还使用以下提供程序包装每个屏幕:
const WrappedSearchScreen = withModalProvider(SearchScreen);
function SearchNavigator() {
const SearchStack = createStackNavigator();
return (
<SearchStack.Navigator>
<SearchStack.Screen
name="Search"
component={WrappedSearchScreen}
/>
...
</SearchStack.Navigator>
);
}
...
import { Alerts } from "./Alerts";
import { useStore } from "./store";
export const withModalProvider = (Component: FC) => () => {
const progressBarVisible = useStore((state) => state.progressBarVisible);
return (
<BottomSheetModalProvider>
<Component />
<Alerts />
<ProgressBar
indeterminate
color="green"
visible={progressBarVisible}
style={{ position: "absolute", bottom: 0, left: 0 }}
/>
</BottomSheetModalProvider>
);
};