我正在使用react 导航V6和上下文API,当我从我的组件导航到屏幕时,上下文状态image
即使包装了我的组件,也变成了undefined
.下面是我的组件和屏幕中的代码流和相关代码.
EXPECTED OUTPUT
-> image
context state should persist (as I'm using context provider)
ACTUAL OUTPUT
-> image
context state becomes undefined when I navigate to different screen.
AppStack个
const AppStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name={'AppDrawer'} component={AppDrawer} />
<Stack.Screen name={'StoreStack'} component={StoreStack} />
</Stack.Navigator>
)
}
AppDrawer个
const AppDrawer = () => {
return (
<Drawer.Navigator>
<Drawer.Screen name={'AppBotTab'} component={AppBotTab} />
</Drawer.Navigator>
)
}
AppBotTab个
const BotTab = createBottomTabNavigator();
const AppBotTab = () => {
return (
<BotTab.Navigator>
<BotTab.Screen name='CameraPreview' component={CameraPreview} />
//... other screens
</BotTab.Navigator>
)
}
CameraPreview-gt;罪魁祸首(看起来像)
const CameraPreview = ({ navigation }) => {
const isFocused = useIsFocused();
const cameraRef = React.useRef<ExpoCamera>(null);
const [isCameraReady, setIsCameraReady] = useState(false);
const [cameraType, setCameraType] = useState(CameraType.back);
return (
isFocused && (
<Camera
cameraRef={cameraRef}
cameraType={cameraType}
flashMode={flashMode}
onCameraReady={() => setIsCameraReady(true)}>
<MediaContextProvider>
<CameraControls
isCameraReady={isCameraReady}
onToggleCamera={toggleCamera}
setFlashMode={setFlashMode}
cameraRef={cameraRef}
onDismiss={() => navigation?.goBack()}
/>
</MediaContextProvider>
</Camera>
)
);
}
CameraControls个
const CameraControls = () => {
const { image, setImageAndUpdateSize } = useMedia();
const [cameraState, setCameraState] = useState('PREVIEW');
useEffect(() => {
console.log('Mounting CAMERA CONTROLS');
return () => {
console.log('image: ', image); // undefined
console.log('Umnounting CAMERA CONTROLS'); // gets called when navigating to StoreStack screen
};
}, []);
const takePhoto = async () => {
if (cameraRef.current) {
const data = await cameraRef.current.takePictureAsync(CAMERA_OPTIONS);
const source = data.uri;
if (source) {
setImageAndUpdateSize({ path: source })
cameraRef.current.pausePreview();
setCameraState('IMAGE_PREVIEW');
}
}
};
switch (cameraState) {
case 'PREVIEW':
return <CameraPreviewControls onTakePhoto={takePhoto} />;
case 'IMAGE_PREVIEW':
if (!image?.path) return null;
return <PhotoPreview imageURI={image?.path} />;
default:
return null;
}
}
PhotoPreview个
const PhotoPreview = ({ imageURI }) => {
useEffect(() => {
console.log('Mounting PHOTO REVIEW');
return () => {
console.log('Umnounting PHOTO PREVIEW'); // gets called when navigating to StoreStack screen
};
}, []);
return (
<ImageBackground source={{uri:imageURI}} />
//... other components
<FiltersPanel />
)
}
FiltersPanel个
const FiltersPanel = () => {
...
return (
//...
<Gifts />
)
}
Gifts Component个
const Gifts = () => {
const navigation = useNavigation();
const goToStore = () => {
navigation.navigate('StoreStack', {
screen: StoreStackPages.StoreScreen,
});
};
return (
<TouchableOpacity onPress={goToStore}>
<Image source={GIFT} resizeMode="contain" style={styles.image} />
</TouchableOpacity>
);
}
MediaContext个
const MediaContext = createContext({
// other default values
setImage: () => {},
});
const MediaContextProvider = ({ children }) => {
const [image, setImage] = useState<Partial<PickerImage>>();
// other states
return (
<MediaContextProvider value={{image, setImage}}></MediaContextProvider>
)
}
export const useMedia = () => {
const context = useContext(MediaContext);
const setImageAndUpdateSize = (capturedImage) => {
const {setImage} = context;
return setImage(capturedImage);
}
return {
...context,
// other functions & utilities
setImageAndUpdateSize
}
}
这就是整个流程.所以,简单地说,问题是when I capture a photo in 100, the 101 is set successfully and as the 102 now changes to 'IMAGE_PREVIEW', the 103 component gets mounted, and I can see the 104 loaded with my context 101, now when I tap the 106 icon (being in the 103 component), I navigate to 108, BUT NOW when I go back from StoreStack, the context 101 changes to 110 and the 102 changes to 112,这不应该是这种情况,因为我仍然被包装在MediaContextProvider
下,所以image
上下文状态不应该是undefined
,而且当我导航到StoreStack并出现时,CameraControls
和PhotoPreview
组件被卸载,这在React导航中也不应该是这样的,根据Reaction导航文档,当我们导航到一个屏幕时,前一个屏幕不会被卸载.
如果有人能解释一下这一点,那将是非常有用的!!
提前谢谢您!