skip to Main Content

I have a project in Expo React Native where I use the map function to render elements with data. One of the elements is a photo that needs to be displayed only when the button is pressed.

I tried this but it shows and hides all the photos.

const [showPhoto, setShowPhoto] = useState(false);
//...
{readings.map(
                (
                    {
                        metersID,
                        id,
                        date,
                        volume,
                        type,
                    },
                    i
                ) => { return (
//...some elements before this
<TouchableOpacity onPress={() => setShowPhoto(!showPhoto)}>
                                <FontAwesome name="photo" size={40} color="black" />
                            </TouchableOpacity>
                            {showPhoto ? (
                                <ImageViewer
                                    placeholderImageSource=""
                                    selectedImage={readings[i].photo}
                                />
                            ) : null}
//...some elements after this

2

Answers


  1. You should create an array of booleans to track the visibility of each photo individually. Here’s how you can modify your code:

    const [showPhotos, setShowPhotos] = useState(Array(readings.length).fill(false));
    
    // ...
    
    {readings.map(({ metersID, id, date, volume, type }, i) => (
        // ... some elements before this
    
        <TouchableOpacity onPress={() => togglePhotoVisibility(i)}>
            <FontAwesome name="photo" size={40} color="black" />
        </TouchableOpacity>
        {showPhotos[i] ? (
            <ImageViewer
                placeholderImageSource=""
                selectedImage={readings[i].photo}
            />
        ) : null}
    
        // ... some elements after this
    ))}
    
    // ...
    
    function togglePhotoVisibility(index) {
        setShowPhotos(prevShowPhotos => {
            const newShowPhotos = [...prevShowPhotos];
            newShowPhotos[index] = !newShowPhotos[index];
            return newShowPhotos;
        });
    }
    
    Login or Signup to reply.
  2. To show and hide only the specific photo related to the button pressed, you need to track the visibility of each individual photo separately. One approach is to modify your data structure to include a "showPhoto" property for each reading. Here’s how you can achieve that:

    1. Modify your readings data to include a "showPhoto" property:
    const [readings, setReadings] = useState([
      { metersID: 1, id: 101, date: "2023-07-18", volume: 100, type: "Type A", showPhoto: false, photo: "URL_TO_PHOTO_A" },
      { metersID: 2, id: 102, date: "2023-07-19", volume: 200, type: "Type B", showPhoto: false, photo: "URL_TO_PHOTO_B" },
      // Add more readings with their showPhoto property
    ]);
    
    1. Toggle the "showPhoto" property for the specific reading when the button is pressed:
    {readings.map(({ metersID, id, date, volume, type, showPhoto, photo }, i) => {
      return (
        // ... some elements before this
        <TouchableOpacity
          onPress={() => {
            const updatedReadings = [...readings];
            updatedReadings[i].showPhoto = !showPhoto;
            setReadings(updatedReadings);
          }}
        >
          <FontAwesome name="photo" size={40} color="black" />
        </TouchableOpacity>
        {showPhoto ? (
          <ImageViewer placeholderImageSource="" selectedImage={photo} />
        ) : null}
        // ... some elements after this
      );
    })}
    

    By tracking the "showPhoto" property for each reading separately, you can control the visibility of individual photos based on the button press. Each reading in the "readings" array will have its own "showPhoto" property to determine whether the photo should be displayed or not.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search