Search code examples
react-nativeuse-statetouchableopacity

change color when button is pressed and deselect other options


I have 5 options that I wrapped with touchableopacity. I'd like that when one options is clicked that the color turns green. If i click another option then the previous option goes grey and the new option is green. Can someone please help me code this out? I don't want to write a bunch of IF statements. I feel its bad code and there is a faster way of getting to my goal. Don't mind the Alert function there I only had that when i initially setup the touchableopacity.

const [angryColor, setAngryColor] = useState('grey')
    const [sadColor, setEmojiSad] = useState('grey')
    const [neutral, setNuetral] = useState('grey')
    const [happyColor, setHappyColor] = useState('grey')
    const [laughColor, setLaugh] = useState('grey')

 function toggleAngry(){
     if (angryColor === 'grey'){
         setAngryColor('green')
     } else {
         setAngryColor('grey')
     }
    }


    return(
        <View style={styles.screen}>
            <View style={styles.container}>
                <View style={styles.emojiView}>
                    <TouchableOpacity onPress={() => toggleAngry()}>
                        <FontAwesome5 name="angry" size={40} color={angryColor}/>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => Alert.alert('clicked')}>
                        <Entypo name="emoji-sad" size={40} color={sadColor}/>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => Alert.alert('clicked')}>
                        <Entypo name="emoji-neutral" size={40} color={neutral} />
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => Alert.alert('clicked')}>
                        <Entypo name="emoji-happy" size={40} color={happyColor}/>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => Alert.alert('clicked')}>
                        <FontAwesome5 name="laugh-beam" size={40} color={laughColor} />
                    </TouchableOpacity>
                </View>

Solution

  • You can set a single variable and set the colour based on that. There is no need for multiple states. I added a callback function which can be used by the parent component to get this update.

    const EmojiInput = (props) => {
      const [selected, setSelected] = React.useState(0);
    
      const onItemSelected=emoji=>{
        setSelected(emoji);
        if(props.callback){
          props.callback(emoji);
        }
      };
    
      return (
        <View style={styles.emojiView}>
          <TouchableOpacity onPress={() => onItemSelected(1)}>
            <FontAwesome5 name="angry" size={40} color={selected==1?'red':'grey'} />
          </TouchableOpacity>
          <TouchableOpacity onPress={() => onItemSelected(2)}>
            <Entypo name="emoji-sad" size={40} color={selected==2?'red':'grey'} />
          </TouchableOpacity>
          <TouchableOpacity onPress={() => onItemSelected(3)}>
            <Entypo name="emoji-neutral" size={40} color={selected==3?'red':'grey'} />
          </TouchableOpacity>
          <TouchableOpacity onPress={() => onItemSelected(4)}>
            <Entypo name="emoji-happy" size={40} color={selected==4?'red':'grey'} />
          </TouchableOpacity>
          <TouchableOpacity onPress={() => onItemSelected(5)}>
            <FontAwesome5 name="laugh-beam" size={40} color={selected==5?'red':'grey'} />
          </TouchableOpacity>
        </View>
      );
    };