Reputation: 41
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
Upvotes: 0
Views: 211
Reputation: 4642
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>
Upvotes: 1