I’m actualy coding a mobile app for school and I have problems when try to change content of a Text when I’m pressing a TouchableOpacity button.
I want that : When I press the button (actualy a text button) it change the content of a Text by the actual text of the button (imagine menu where you have to chose an app ex: discord/yammer etc… and when you press on the app you want it change the actual ‘…’ by the name of the app)
To do this I wrote this :
const PopupMenuSelect = () => { const [visible, setVisible] = useState(false); const scale = useRef(new Animated.Value(0)).current; let content = '...'; const options = [ { title: 'Spotify', icon: 'spotify', action: () => content = options.title, }, { title: 'Yammer', icon: 'yammer', action: () => content === options.title, }, { title: 'Trello', icon: 'trello', action: () => content === options.title, }, { title: 'Twitter', icon: 'twitter', action: () => content = options.title, }, { title: 'Discord', icon: 'discord', action: () => content === options.title, }, { title: 'Outlook', icon: 'mail-bulk', action: () => content === options.title, }, ] function resizeBox(to){ to === 1 && setVisible(true); Animated.timing(scale,{ toValue:to, useNativeDriver:true, duration:200, easing: Easing.linear, }).start(() => to === 0 && setVisible(false)); } return ( <> <TouchableOpacity onPress={() => resizeBox(1)}> <Text style={[style.subtext, { color: layouts.secondary }]}>{content}</Text> </TouchableOpacity> <Modal transparent visible={visible}> <SafeAreaView style={{ flex: 1 }} onTouchStart={() => resizeBox(0)}> <Animated.View style={[ style.popUp, { opacity: scale.interpolate({ inputRange: [0, 1], outputRange:[0, 1]}) }, { transform: [{ scale }]}, ]} > {options.map((op, i) => ( <TouchableOpacity style={[style.option, { borderBottomWidth: i === options.length - 1 ? 0 : 1 }]} key={i} onPress={op.action}> <Text style={{fontFamily: "Title-Font", fontSize: 15}}>{op.title}</Text> <FontAwesome5 name={op.icon} size={26} color={'black'} style={{marginLeft: 10}}/> </TouchableOpacity> ))} </Animated.View> </SafeAreaView> </Modal> </> ) } export default PopupMenuSelect;
I create a let variable named ‘content’ = ‘…’ and I set the action of the button to replace the content by the title of the ‘option’
like this :
action: () => content = options.title,
but it didn’t work, that didn’t change the content when I press the button (Spotify or something).
Thanks a lot in advance guys, love u
Advertisement
Answer
The view only re-renders when a state changes, content
is a let. You could solve the problem by changing the content to a state. Change the content to the option title when onPress is fired.
const [content, setContent] = useState('') ... <TouchableOpacity ... onPress={() => setContent(op.title)}> ... </TouchableOpacity>
Another option, if you really want to handle it from the action
in the array, could be to pass the option into the function
const options = [ { title: 'Spotify', icon: 'spotify', action: (option) => setContent(option.title), }, .... ]; ... <TouchableOpacity ... onPress={() => op.action(op)}> ... </TouchableOpacity>