Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

change state of clicked target inside mapped array

I’m trying to change the state inside a map array. my state is shared in all the items created by the map array and I’m trying to change the state of the clicked item, here’s the code:

{dbData ?
            dbData.map((item, i) => (
                <Box id={item.id} className={`${cl.FolderStyles} ${activeFolderStyles}`} key={i} onClick={activeFolder}>
                    <FolderIcon className={cl.folder_icon} />
                    {item.name}
                </Box>
            ))
            : <img src={loader} alt="loader" />
        }

here you can see im creating multiple items, and the state is: "activeFolderStyles",
what i want is to add a class to the clicked item which becomes active but my problem is that the state of all the items is changed after clicking and all become active.

            const [activeFolderStyles, setActiveFolderStyles] = useState();
          const activeFolder = (e) => {
            const id = e.target.id;
            const element = document.getElementById(id);
            console.log(element);
            if (element.classList.contains(side_cl.folderActive)) {
              setActiveFolderStyles("");
            }
            else {
              setActiveFolderStyles(side_cl.folderActive);
            }
          }

here is the state that im using.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 const [activeFolderStyles, setActiveFolderStyles] = useState();
  const activeFolder = (e) => {
    const id = e.target.id;
    const element = document.getElementById(id);
    if (element.classList.contains(side_cl.folderActive)) {
      setActiveFolderStyles("");
    }
    else {
      setActiveFolderStyles(side_cl.folderActive);
    }

}

So i dont really know how to point out the targeted state and not all

>Solution :

You can maintain some state that defines what the currently active folder is. The state will identify the currently active folder using its id, which can be obtained when you map dbData. While mapping, you can check if the current item.id of the current item is equal the active id in your state, and if it is, add your class, otherwise, don’t add the class at all (note, activeFolder in the below JSX refers to the new state value we’re creating to keep track of the active folder id, not your click event handler function from your question):

{dbData ?
  dbData.map((item, i) => (
    <Box id={item.id} className={`${cl.FolderStyles} ${item.id === activeFolder ? side_cl.folderActive : ""}`} key={item.id} onClick={() => handleFolderClick(item.id)}>
      <FolderIcon className={cl.folder_icon} />
      {item.name}
    </Box>
   ))
   : <img src={loader} alt="loader" />
}

Then you can create your activeFolder state:

const [activeFolder, setActiveFolder] = useState();

You can then update this state when you click your folder to the current folder:

// Use this instead of your `activeFolder` function
const handleFolderClick = (newItemId) => {
  // If the folder we're activating is already "active", deactivate it, otherwise, update the state to point to activate our new folder
  setActiveFolder(currItemId => currItemId === newItemId ? "" : newItemId);
}

The above JSX uses the above handleFolderClick function by passing through the item id of the box that was clicked.

Side note: DOM methods like getElementById(), querySelectorAll() etc. are rarely ever used in React, if you find yourself using them then there is a good chance that you’re not doing something in the way it was intended, where a component’s state should be used to help drive the component logic and what it renders.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading