useBottomSheetModal problem useCallback internal parameters that do not update
See original GitHub issueBug
Hi @gorhom , i am having the following problem, i am using present by useBottomSheetModal, as you can see from the image through the buttons i should change the theme.
The status is not updated internally, only when you reopen the BottomSheetModal the status is updated.
How can I solve?
Environment info
Library | Version |
---|---|
@gorhom/bottom-sheet | 1.4.1 |
react-native | 0.63.3 |
react-native-reanimated | 1.13.2 |
react-native-gesture-handler | 1.8.0 |
Reproducible sample code
import React, {
useState,
useEffect,
useCallback,
useMemo,
useRef,
} from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { View, StyleSheet, Image, Dimensions } from 'react-native';
import { Text, Button, RadioButton } from 'react-native-paper';
import {
Common,
Fonts,
Gutters,
Layout,
Images,
Colors,
ColorsDarkMode,
} from '@/Theme';
import { useTranslation } from 'react-i18next';
import Settings from '@/Store/Settings/Init';
const { width: SCREEN_WIDTH } = Dimensions.get('screen');
import AppIntroSlider from 'react-native-app-intro-slider';
import {
BottomSheetModalProvider,
useBottomSheetModal,
BottomSheetOverlay,
} from '@gorhom/bottom-sheet';
import withModalProvider from './withModalProvider';
import BlurredBackground from './BlurredBackground';
const styles = StyleSheet.create({
slide: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
image: {
width: 320,
height: 320,
marginVertical: 32,
resizeMode: 'stretch',
},
text: {
color: 'rgba(255, 255, 255, 0.8)',
textAlign: 'center',
},
title: {
fontSize: 22,
color: 'white',
textAlign: 'center',
},
blurView: {
...StyleSheet.absoluteFillObject,
},
container: {
...StyleSheet.absoluteFillObject,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
overflow: 'hidden',
},
androidContainer: {
backgroundColor: 'rgba(255,255,255, 0.95)',
},
indicator: {
alignSelf: 'center',
width: (8 * SCREEN_WIDTH) / 100,
height: 5,
borderRadius: 4,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
});
const IndexInstallationContainer = (props) => {
const { t } = useTranslation();
const dispatch = useDispatch();
const settings = useSelector((state) => state.settings);
const { present } = useBottomSheetModal();
const handlePresentPress = useCallback(() => {
present(
<View style={{ flex: 1, backgroundColor }}>
<Text>{settings.item.colorScheme}</Text>
<RadioButton.Group
onValueChange={(newValue) => changeButtonTheme(newValue)}
value={settings.item.colorScheme}>
<View style={(Layout.row, Layout.rowHCenter)}>
<RadioButton value="light" />
<Text>Light</Text>
</View>
<View style={(Layout.row, Layout.rowHCenter)}>
<RadioButton value="dark" />
<Text>Dark</Text>
</View>
</RadioButton.Group>
</View>,
{
snapPoints: ['20%'],
animationDuration: 300,
overlayComponent: BottomSheetOverlay,
overlayOpacity: 0.5,
dismissOnOverlayPress: true,
handleComponent: handle,
//backgroundComponent: BlurredBackground,
//onChange: handleChange,
}
);
}, [present, dispatch, settings]);
const slides = [
{
key: 'one',
title: t('welcome'),
text: '',
image: Images.logo,
backgroundColor: '#2196f3',
},
{
key: 'two',
title: t('change.language'),
text: '',
backgroundColor: '#ffc107',
},
{
key: 'three',
title: t('change.mode'),
text: '',
backgroundColor: '#4caf50',
},
];
const changeTheme = () => {
dispatch(
Settings.action({
colorScheme: settings.item.colorScheme === 'dark' ? 'ligth' : 'dark',
})
);
};
const changeButtonTheme = (colorScheme) => {
dispatch(Settings.action({ colorScheme }));
};
const openBottom = () => setState((prev) => ({ ...prev, open: !prev.open }));
const b = (
<Button
style={[Gutters.largeHMargin, Gutters.largeBMargin]}
raised
mode="contained"
onPress={handlePresentPress}>
{t('actions.change')}
</Button>
);
const _renderItem = ({ item }) => {
return (
<View style={[styles.slide, { backgroundColor: item.backgroundColor }]}>
{item.image && <Image source={item.image} style={styles.image} />}
<Text style={styles.title}>{item.title}</Text>
{item.key === 'three' && b}
<Text style={styles.text}>{item.text}</Text>
</View>
);
};
const _onDone = () => {
//console.log(props)
props.navigation.navigate('Login');
};
const [state, setState] = useState({
open: false,
});
const { open } = state;
const backgroundColor =
settings.item.colorScheme === 'dark'
? ColorsDarkMode.backgroundPrimary
: Colors.backgroundPrimary;
const handle = () => {
return (
<View
style={{
paddingHorizontal: 16,
paddingVertical: 5,
backgroundColor,
}}>
<View
style={[
styles.indicator,
{
backgroundColor:
settings.item.colorScheme === 'light'
? 'rgba(0, 0, 0, 0.25)'
: 'rgba(255, 255, 255, 0.25)',
},
]}
/>
</View>
);
};
return (
<>
<AppIntroSlider
renderItem={_renderItem}
data={slides}
onDone={_onDone}
nextLabel={t('next')}
doneLabel={t('done')}
/>
</>
);
};
export default withModalProvider(IndexInstallationContainer);
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (2 by maintainers)
Top Results From Across the Web
Use 'gorhom/bottom-sheet' React Native, Hooks can only be ...
The onPress function for the TouchableOpacity seems to be a problem here. Use some state to show or hide the BottomModel accordingly
Read more >React Hooks cheat sheet: Best practices with examples
If you find that useState / setState are not updating immediately, the answer is simple: they're just queues. React useState and setState don't...
Read more >Scrollables | React Native Bottom Sheet - GitHub Pages
This library provides a pre-integrated virtualized lists that utilize an internal functionalities with the bottom sheet container to allow smooth panning ...
Read more >Common use cases for useCallback? : r/reactjs - Reddit
I know useCallback is used for memoizing functions so that they ... is passed around it can become stale (internal variables are not...
Read more >A Performant Interactive Bottom Sheet with Fully Configurable ...
To enable or disable user interaction with the sheet. ... Animated value to be used as a callback for the position node internally....
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
hi @Angelk90 , the solution would be to make the modal an uncontrolled component that updates parent when value change also it contain its own state. read more
here is a working example:
Hi @maxckelly , I believe we have to wait @gorhom to find out more.