useState variables doesn't seem to work with Photo Sphere Viewer handleClick function

31 views Asked by At

I am trying to mutate a component using useState, the problem is that I can modify the useState AddPin from false to true, but the changes are not reflected when I click the ReactPhotoSphereViewer component. The system has a simple button and a textbox as you can see in the example bellow:

import React, { useState } from 'react';
import { Grid, Typography, Button, TextField } from "@material-ui/core";
import { ReactPhotoSphereViewer } from 'react-photo-sphere-viewer';
import PANOVIEW from './assets/img/SAG.png';

function App() {

  const [PinText,setPinText] = useState('');
  const [AddPin,setAddPin] = useState(false);

  const handlePinTextChange = (e) => {
    setPinText(e.target.value)
  }

  const handleNewPinButton = () => {
    setAddPin(true)
  }

  const handlePanoClick = () => {
    console.log(AddPin)
  }

  return (
    <React.Fragment>

      <Grid container>

        <Grid item xs={2} style={{ padding: "10px" }}>

          <Grid container>

            <Grid item xs={12} style={{ padding: "10px" }}>
              <Typography style={{ fontWeight: "bold" }}>AÑADIR:</Typography>
            </Grid>
            <Grid item xs={12} style={{ padding: "10px" }}>
              <Typography>
                Añade un pin con un texto.
              </Typography>
            </Grid>
            <Grid item xs={12} style={{ padding: "10px" }}>
              <TextField id="outlined-basic" label="Texto Pin" variant="outlined" value={PinText} onChange={(e) => handlePinTextChange(e)} />
            </Grid>
            <Grid item xs={12} style={{ padding: "10px" }}>
              <Button variant="contained" onClick={handleNewPinButton}>Añadir Pin</Button>
            </Grid>

            {AddPin ? (
              <>{PinText}</>
            ):(
              <>falso</>
            )}

          </Grid>

        </Grid>
        <Grid item xs={10}>

          <ReactPhotoSphereViewer 
            src={PANOVIEW}
            height='100vh'
            width="100%"
            onClick={handlePanoClick}
            ></ReactPhotoSphereViewer>

        </Grid>

      </Grid>

    </React.Fragment>
  );
}

export default App;

The problem is that the useState variable AddPin is changed to true when I click the button, and when I click the Panoramic view component it should show me that is true, but instead it shows me that is false. As if the change was never done in the useState variable.

Any help will be thanked.

I have tried using regular variables (var and let) but I need useState because I need to mutate components according to the changes I go making in my webpage.

1

There are 1 answers

0
alexolguin On BEST ANSWER

I solved the problem. Aparently there is a problem with the ReactPhotoSphere functions that doesn't allow to use external useState variables but you can set the internal data to useState variable, how so? You can't get the changes from the variables but you can change the variables by the inside. Therefore I just externalized all important functions and added the click function not to the PhotoSphere component but the parent component, which can be a div or anything else. With that I preserve both click function that execute equaly and I get the data passed into a useSatet variable that is passed at the same time to the parent object click function:

import React, { useRef, useState } from 'react';
import { Grid, Typography, Button, TextField, Divider, Paper, Table, TableHead, TableRow, TableCell, TableBody, IconButton } from "@material-ui/core";
import TableContainer from '@mui/material/TableContainer';
import { ReactPhotoSphereViewer, MarkersPlugin } from 'react-photo-sphere-viewer';
import DeleteIcon from '@mui/icons-material/Delete';
import PANOVIEW from './assets/img/SAG.png';
import PIN from './assets/img/pin-blue.png';

function App() {
  const pSRef = useRef();
  const [markerPlugs,setMarkerPlugs] = useState(null);
  const [PinText,setPinText] = useState('');
  const [AddPin,setAddPin] = useState(false);
  const [yaw,set_yaw] = useState(0);
  const [pitch,set_pitch] = useState(0);
  const [markers,setMarkers] = useState([]);
  const [pin_id,set_pin_id] = useState(0);
  const plugins = [
   [ MarkersPlugin, { markers: markers } ]
  ]

  const handleReady = (instance) => {
   const markersPlugs = instance.getPlugin(MarkersPlugin);
   setMarkerPlugs(markersPlugs)
   markersPlugs.addEventListener("select-marker", (data) => {
     console.log(data.marker.config.id)
   })
  }

  const handlePinTextChange = (e) => {
   setPinText(e.target.value)
  }

  const handleNewPinButton = () => {
    setAddPin(true)
  }

  const handlePinAddition = () => {
   if (AddPin) {
     if (!markerPlugs) 
       return;
     markerPlugs.addMarker(
       {
         // image marker that opens the panel when clicked
         id: "PIN_"+pin_id,
         position: { yaw: yaw, pitch: pitch },
         image: PIN,
         anchor: "bottom center",
         size: { width: 50, height: 50 },
         tooltip: PinText,
       }
     )
     setMarkers([...markers, {
       // image marker that opens the panel when clicked
       id: "PIN_"+pin_id,
       position: { yaw: yaw, pitch: pitch },
       image: PIN,
       anchor: "bottom center",
       size: { width: 50, height: 50 },
       tooltip: PinText,
     }])
     set_pin_id(pin_id+1)
     setAddPin(false)
     setPinText('')
   }
 }

  const handlePanoClick = (data) => {
   set_yaw(data.data.yaw)
   set_pitch(data.data.pitch)
  }

  return (
    <React.Fragment>

    <Grid container>

    <Grid item xs={2} style={{ padding: "10px" }}>

      <Grid container>

        <Grid item xs={12} style={{ padding: "10px" }}>
          <TableContainer component={Paper} style={{ maxHeight: 300 }}>
            <Table sx={{ minWidth: 650 }} aria-label="simple table">
              <TableHead>
                <TableRow>
                  <TableCell>ID</TableCell>
                  <TableCell>Texto</TableCell>
                  <TableCell></TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {render_pins()}
              </TableBody>
            </Table>
          </TableContainer>
        </Grid>

      </Grid>

    </Grid>
    <Grid item xs={10} onClick={handlePinAddition}>

      <ReactPhotoSphereViewer 
        ref={pSRef}
        src={PANOVIEW}
        height='100vh'
        width="100%"
        onClick={handlePanoClick}
        onReady={handleReady}
        plugins={plugins}
        ></ReactPhotoSphereViewer>

    </Grid>

  </Grid>

  </React.Fragment>
  )


}