I'm starting to learn React Native, and for my project I created a simple Button component to reuse in my project. I set the opacity value dynamically according to the variable 'disabled', however, the look of the button is not changing with the value of the opacity variable. I searched around and I have not found an explanation..
Any help will be appreciated.
Here is my source code:
import React from 'react'
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
import PropTypes from 'prop-types'
//TODO: arrumar o problema com a opacidade
export default function Button({text, onPress, style, disabled, textStyle}) {
let opacity = disabled === true ? 0.5 : 1
// console.log('opacity', opacity)
return (
<TouchableOpacity onPress={onPress} style={[defaultStyles.button, style, {opacity: opacity}]}
disabled={disabled}>
<Text style={[defaultStyles.text, textStyle]}>{text}</Text>
</TouchableOpacity>
)
}
const defaultStyles = StyleSheet.create({
text: {
color: 'white'
},
button: {
backgroundColor: 'black',
margin: 15,
padding: 15,
borderRadius: 10
},
})
Button.propTypes = {
text: PropTypes.string,
onPress: PropTypes.func,
style: PropTypes.oneOfType([
PropTypes.string,
PropTypes.array,
PropTypes.object
]),
disabled: PropTypes.bool,
textStyle: PropTypes.oneOfType([
PropTypes.string,
PropTypes.array,
PropTypes.object
])
}
EDIT: Here is the code the calls the button
class NewDeck extends Component {
state={
title: null
}
submit = () => {
const { add, goBack } = this.props
let deck = {...this.state}
if(!deck['deckId']){
deck['deckId'] = Date.now()
deck['logs'] = []
}
!deck['cardsId'] && (deck['cardsId'] = [])
add(deck).then(() => {
this.props.navigation.navigate('Deck', {deckId: deck.deckId, title: deck.title})
this.setState({title: null})
}
)
}
render(){
const disabled = this.state.title === null || this.state.title.length === 0
return (
<KeyboardAwareScrollView resetScrollToCoords={{ x: 0, y: 0 }}
contentContainerStyle={styles.container}>
<Text style={textStyles.title2}>Whats the title of your deck?</Text>
<TextInput editable={true} style={[styles.input, textStyles.body]}
placeholder='Type title here'
maxLength={25}
value={this.state.title}
onChangeText={(text) => {
this.setState({title: text})
}}
/>
<Button
onPress={this.submit}
text='Submit'
style={{backgroundColor: colors.pink}}
textStyle={textStyles.body}
disabled={!this.state.title}
/>
</KeyboardAwareScrollView>
)
}
}
The disabled variable is true if the title of the newDeck component is empty or null. When this variable is true, the opacity of the button should be only 0.5. When the value goes to false, then the opacity changes to 1 again. If I log the value of the opacity in the component, I can see it going from 0.5 to 1, but the look of the component doesn't change.
In other words, component does not reload so componentDidMount() won't be called again. Better to use state management like Redux or Mobx. Let them handle the changes instead of reading from asyncStorage. If a Mobx Store gets updated it'll automatically refresh your values wherever you are accessing it.
To change the opacity for a color in a React component, we can use the color NPM package. We call Color with the color name. And we change the alpha value with the alpha method. Finally, we return the color code of that color with the string method.
not sure if it's a bug on the TouchableOpacity component, but the opacity won't update on a re-render until the component is clicked
to fix your problem just wrap the content of the touchable in a View and apply the opacity to the view instead of the touchable
export default function Button({text, onPress, style, disabled, textStyle}) {
const opacity = disabled === true ? 0.5 : 1
// console.log('opacity', opacity)
return (
<TouchableOpacity onPress={onPress} disabled={disabled}
style={[defaultStyles.button, style]}>
<View style={{opacity}}>
<Text style={[defaultStyles.text, textStyle]}>{text}</Text>
</View>
</TouchableOpacity>
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With