Home > Software design >  Displaying Popup for Single Array Element from API Call ReactJS
Displaying Popup for Single Array Element from API Call ReactJS

Time:12-23

Sorry if I worded this poorly, it's my first question, and I'm also new to JS/React in general...

I have mapped through an array from an API call and displayed the information I need; how can I show a popup for a single element in the array returned rather than displaying the information for all elements?

        import React, {useState, useEffect, useCallback} from 'react'
import axios from 'axios';
import Popup from 'reactjs-popup';
import 'reactjs-popup/dist/index.css';

function Agents() {

    let [responseData, setResponseData] = useState([]);
    let [doneLoading, setdoneLoading] = useState(false);
    let [open, setOpen] = useState(false);
    let closePopup = () => setOpen(false);
  
    const fetchData = useCallback(() => {
        axios({
          method: 'GET',
          url: 'https://valorant-api.com/v1/agents',
          params: {language: 'en-US', isPlayableCharacter: true}
        })
        .then((response) => {
          setResponseData(response.data.data.map(m => ({a: m.displayName, b: m.mapUrl, c: m.displayIcon})))
          console.log(responseData)
          setdoneLoading(true)
        })
        .catch((error) => {
          console.log(error)
        })
      }
    )
  
    useEffect(() => {
      fetchData()
    }, []) // pass an empty array as the dependencies
  
    return (
        <div>
            <h1 >Valorant Agents</h1>
            <h2 >Click on an agent to learn more</h2>
            <div  key={responseData}>

                {doneLoading ? 
                Object(responseData).map((maps, index) => {
                console.log( JSON.stringify(maps)   "Hex?")
                return (
                    <div key={responseData.maps} >

                        <div  onClick={() => setOpen(true)}>
                          <p >{`${index 1}. ${maps.a}`}</p>
                          <img src={maps.c} alt="#" width="75px" /> 
                          <div onClick={() => setOpen(true)} >Learn more</div>
                        </div>
                        {open ? 
                        <>
                        <div >Returned API information would go here</div>
                        <button onClick={closePopup} >Close</button>
                        </>
                        : null}
                                            
                    </div>  
                    )
                })
                : console.log("loading")
                }
            </div>
        </div>
    );
}

export default Agents

So in the code above, I toggle a (not so styled yet) popup which should display information for the individual div clicked; however, it shows the information for all instead. I was hoping someone could educate me as I'm still learning; all I've gathered so far is that it displays all the information inside the map method. I'm just not sure how to approach it outside of that.

Edit - Here is a CodeSandbox Link; if you click to learn more, it displays on all the characters, but I only want it for the individual one clicked.

CodePudding user response:

Try this~~~

Here is updated link: codesandbox

You can view code start with Line 36, The component PopUp can change to want you want (I just write ii in most simple way)

The main knoweldge is you should pass the data to PopUp component.

...
  const [showData, setShowData] = useState();
  const PopUp = (props) => {
    return (
      <div>
        <h1>{props.data.a}</h1>
        <div >
          Returned API information would go here
        </div>
        <button
          onClick={closePopup}
          
        >
          Close
        </button>
      </div>
    );
  };
  const throwDataToPopUp = (data) => {
    setOpen(true);
    setShowData(data);
  };
...

CodePudding user response:

When we click on any item, we should catch that data in a state. Then, we should show that state data in the popup.

const [modalData, setModalData] = React.useState(null); // this state is to store the item data
const [open, setOpen] = React.useState(false);

const handleModalOpen = (itemData) => {
  setModalData(itemData);   
  setOpen(true);
};

const closeModal = () => {
   setModalData(null);
   setOpen(false);
};
    
return (
      <div>
            <h1 >Valorant Agents</h1>
            <h2 >Click on an agent to learn more</h2>
            <div  key={responseData}>

                {doneLoading ? 
                Object(responseData).map((maps, index) => {
                console.log( JSON.stringify(maps)   "Hex?")
                return (
                    <div key={responseData.maps} >

                        <div  onClick={() => handleModalOpen(maps)}>
                          <p >{`${index 1}. ${maps.a}`}</p>
                          <img src={maps.c} alt="#" width="75px" /> 
                          <div onClick={() => handleModalOpen(maps)} >Learn more</div> // When we click on there, it saves the item data we are getting as maps into state and opening the popup same time.
                        </div>
                        {open ? 
                        <>
                        <div >Returned info would go here</div>
                        <button onClick={closeModal} >Close</button>
                        </>
                        : null}
                                            
                    </div>  
                    )
                })
                : console.log("loading")
                }
            </div>
            <Modal open={open} data={modalData} /> // Suppose this one is your popup. You will consume the item data inside the popup as data. Now use it as you want.
        </div>);

CodePudding user response:

You can filter the array if you don't want to display all the array

Object(responseData).filter((item)=> item.id = "0")

  • Related