Home > OS >  React Native, how to change display of touchable opacity to visible when clicking on another, and in
React Native, how to change display of touchable opacity to visible when clicking on another, and in

Time:05-19

As the title suggests, I am struggling to find a way to make my touchable opacities have a display of none by default (well, I suppose that is easy enough with a styling of display: none), but I'm not able to figure out how to toggle that using a touchable opacity.

In my head, the logic is to have the state change from true to false onpress, and false is visible while true is invisible. However, I can't muster up the knowledge to code it out. Here is what I have so far, more info below code:

import React, {useState} from 'react';
import { KeyboardAvoidingView, StyleSheet, Text, View, TextInput, TouchableOpacity, Keyboard, ImageBackground } from 'react-native';
import Task from './components/task';

const plus = {uri: 'https://media.discordapp.net/attachments/639282516997701652/976293252082839582/plus.png?width=461&height=461'};
const done = {uri: 'https://media.discordapp.net/attachments/736824455170621451/976293111456231434/done.png?width=461&height=461'};
const exit = {uri: 'https://media.discordapp.net/attachments/639282516997701652/976293251759898664/exit.png?width=461&height=461'};
const cog = {uri: 'https://media.discordapp.net/attachments/639282516997701652/976293672884789288/cog.png?width=461&height=461'};

function App() {
  const [task, setTask] = useState();
  const [taskItems, setTaskItems] = useState([]);
  const buttons = {plus, done, exit, cog}
  const [selected, setSelected] = useState(buttons.plus)

  const [done, setDone] = useState(buttons.plus);

  const openMenu = () => {
    setSelected(buttons.exit);

    //Make 'done' and 'cog' TouchableOpacity(s) visible. Click again and they become invisible.
    //this.setState({ visible : !this.state.visible}) This makes visible invisible if not invisible already.
    //visible should be the name of a state.

    {/*handleAddTask();*/}
  }

  const handleAddTask = () => {
    setDone(buttons.done);
    Keyboard.dismiss();
    setTaskItems([...taskItems, task]); {/*Puts out everything in the taskItems as a new array then appends the new task to it */}
    setTask(null);
    setSelected(buttons.plus) //Makes exit button go back to plus because it shows that its finished. DO same for display none for extended buttons when I figure it out.
  }

  const completeTask = (index) => {
    let itemsCopy = [...taskItems];
    itemsCopy.splice(index, 1);
    setTaskItems(itemsCopy);
  }

  return (
    <View style={styles.container}>
      
    {/*Tasks*/}
    <View style={styles.tasksWrapper}>
      <Text style={styles.sectionTitle}>Tasks</Text>

      <View style={styles.items}>
      {/*This is where tasks go*/}
      {
        taskItems.map((item, index) => {
              return (
                <TouchableOpacity key={index}  onPress={() => completeTask(index)}>
                  <Task text={item} /> 
                </TouchableOpacity>
              )
            })
          }
        </View>
      </View>

    {/*Write a task*/} 
    <KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : "height"} style={styles.writeTaskWrapper}>
    

      <TextInput style={styles.input} placeholder={'Write a task'} value={task} onChangeText={text => setTask(text)}/>

    <View style={styles.buttonRow}>

    <TouchableOpacity onPress={() => openConfig()}> 
      {/* Opens config for creation (i.e. calendar, timer, repetition, etc). */}
        <View style={styles.addWrapper}>
          <ImageBackground source={buttons.cog} alt='button' resizeMode="cover" style={styles.plusButton} />
        </View>
      </TouchableOpacity>

      <TouchableOpacity onPress={() => handleAddTask()}> 
      {/* Done (check) button which does handleAddTask. */}
        <View style={styles.addWrapper}>
          <ImageBackground source={buttons.done} alt='button' resizeMode="cover" style={styles.plusButton} />
        </View>
      </TouchableOpacity>

      <TouchableOpacity onPress={() => openMenu()}> 
      {/* Onpress opens menu, then shows exit button to go back and revert menu to one button. */}
        <View style={styles.addWrapper}>
          <ImageBackground source={selected} alt='button' resizeMode="cover" style={styles.plusButton} />
        </View>
      </TouchableOpacity>
      
    </View>
      

    </KeyboardAvoidingView>
  </View>
  );
}

The three touchable opacities at the bottom are what I'm trying to change. The first two should by default be invisible, and I think I can do that by assigning useState(false) for them and false should make their display none. Then on the click of the third touchable opacity, it changes their previous state => !previous state.

However, I'm not sure how to code this out and am quite confused. Any help is appreciated. Thanks!

CodePudding user response:

This can be done using conditional rendering. You will either need a state for each of the buttons or a state that holds an array.

Here is a minimal example which works in general.

function App() {
    const [isAVisible, setAVisible] = useState(true);
    const [isBVisible, setBVisible] = useState(false);

    return (
        <View>
            {isAVisible && ( 
               <TouchableOpacity onPress={() => setIsBVisible(prev => !prev)}}>
                   <Text>Toggle Visibility of B</Text>
               </TouchableOpacity>
            )}
            {isBVisible && (
               <TouchableOpacity onPress={() => setIsAVisible(prev => !prev)}}>
                   <Text>Toggle Visibility of A</Text>
               </TouchableOpacity>
            )}
        </View>
    )
}

The above creates two TouchableOpacity. The first toggles the visibility of the second one, and the second one toggles the visibility of the first one. Notice, that the default state of the second one is set to false, thus it will be not be visible on first render.

  • Related