0

I am kind of stuck I have JSON file which has arrays, so I want to when I click on the div to open only one "array" instead of that it opens them all, basically I want to switch between them. I would be very grateful if you could help me .Thanks in Advance . Edit I have more arrays in json file now it double renders them

[
{

"id":0,
 "name": "Aatrox",
"image": "/champions/Aatrox_0.jpg",

"textQ":"Q",
"qInfo": "The darlking Blade Aatrox slams his greatsword down, dealing physical damage. He can swing three times, each with a different area of effect",
"image1": "/spell/AatroxQ.png",          
"textW": "W",
 "wInfo": "Aatrox smashes the ground, dealing damage to the first enemy hit. Champions and large monsters have to leave the impact area quickly or they will be dragged to the center and take the damage again.",
 "image2" : "/spell/AatroxW.png",
 "textE" : "E",
 "eInfo" : " Passively, Aatrox heals when damaging enemy champions. On activation, he dashes in a direction.",
 "image3" :"/spell/AatroxE.png",
 "textR" : "R",
 "RInfo" : "Aatrox unleashes his demonic form, fearing nearby enemy minions and gaining attack damage, increased healing, and movement speed. If he gets a takedown, this effect is extended."    , 
 "image4" : "/spell/AatroxR.png"
}

]
import React  from 'react'
import data from './data.json'
import  './Champions.css'

function Champions() {
  const[toggleShow, setToggleShow]= React.useState(false) 
      
    return (
       <div className='champions'>
       {data.map((postData)=>{
        console.log(postData);
         return(      
           <div onClick={()=> setToggleShow((toggleShow) =>!toggleShow)}key= 
           {postData.id}>
          <div className='champion'>       
         <img className='champion__Image'src={postData.image}></img>                   
          <h4 className="champion__Name">{postData.name}</h4>  
          
           {!toggleShow && 
            <Skills/>}
          </div>
         
          </div>
       )

Skills Component
import React from 'react';
import "./Skills.css";
import data from './data.json'

function Skills () {
             
    return (       
            <div className="spells">
        {data.map((postData)=>{
            console.log(postData)       
            return(
                <div>                 
                   <img alt="123"className='image__Q'src={postData.image1}></img>
                    <p>{postData.textQ}</p>
                    <h4>{postData.qInfo}</h4>
                   <img alt="123"className='image__Q'src={postData.image2}></img>
                    <p>{postData.textW}</p>
                    <h4>{postData.wInfo}</h4>
                    <p>{postData.textE}</p>
                    <h4>{postData.eInfo}</h4>
                    <p>{postData.textR}</p>
                    <h4>{postData.RInfo}</h4>
                   
                    </div>     
  )
  
   })}
   </div>
        
    )
}

export default Skills


9
  • Place each one into another component, and then each one will have it's own state. The trick with React, don't create huge single components, but compose them from lots of smaller ones. Do this, and it all becomes a lot easier. Commented Nov 20, 2020 at 15:37
  • Did that the First time Commented Nov 20, 2020 at 16:03
  • @Keith Did not work Commented Nov 20, 2020 at 17:58
  • That's how you do it, show us your first attempt were you did this, and then we might be able to see were you went wrong. Commented Nov 20, 2020 at 18:21
  • @Keith Here you go Commented Nov 20, 2020 at 19:04

1 Answer 1

1

If I understood good, you will have many object in the JSON, and you want to only get one object?

If so, this will work

import ReactDOM from "react-dom";
import React, { useState } from "react";
import "./styles.css";
import data from "./data.json";

const Champions = () => {
  const [toggleShow, setToggleShow] = useState(false);
  const [currentSelectedChampion, setCurrentSelectedChampion] = useState({});

  const handleSelectChampion = (id) => {
    if (!toggleShow) setToggleShow(true);
    const currentChampion = data.filter((champ) => champ.id === id)[0];
    setCurrentSelectedChampion(currentChampion);
  };

  return (
    <div className="champions">
      {data.map((postData) => {
        return (
          <div onClick={() => handleSelectChampion(postData.id)}>
            <div className="champion">
              <img className="champion__Image" src={postData.image}></img>
              <h4 className="champion__Name">{postData.name}</h4>
              {toggleShow && currentSelectedChampion.id === postData.id && (
                <>
                  <Skills currentChampion={currentSelectedChampion} />
                  <p onClick={() => setToggleShow(false)}>Close</p>
                </>
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
};

const Skills = ({ currentChampion }) => {
  return (
    <div className="spells">
      <div>
        <h1>{currentChampion.name}</h1>
        <p> {currentChampion.textQ}</p>
        <h4>{currentChampion.qInfo}</h4>
        <p> {currentChampion.textW}</p>
        <h4>{currentChampion.wInfo}</h4>
        <p> {currentChampion.textE}</p>
        <h4>{currentChampion.eInfo}</h4>
        <p> {currentChampion.textR}</p>
        <h4>{currentChampion.RInfo}</h4>
      </div>
    </div>
  );
};

ReactDOM.render(<Champions />, document.getElementById("root"));

However, I recommend you to refactor your architecture and wrapp skills and champions in a main component, and passe directly the current champion to each of them. So you will have to filter your data only once. The codesandbox link is here: https://codesandbox.io/s/heuristic-blackwell-sqybi?file=/src/App.js:0-960

Image result :enter image description here

Sign up to request clarification or add additional context in comments.

11 Comments

I want when I click on the specific champ that it displays info only about that one
Yes. but the json file you've puted on the top only show one object in the array. You're meaning there is multiple objects normally on the array and you want to get the single object corresponding to the the champ ? If so, my answer is the way to go, you just need to filter by name, or id, or whatever you get the value from
They are multiple objects in the array, I want to when i click on the specific image that opens up info for that champ
I've updated the code, and its works perfectly, i've added some refactor aswell, please let me know if you have errors or validate the answer if it fits for you, the full code is on the codesanbox by the way
this is before imgur.com/W76AIOM this is what happens when I click on img imgur.com/xTSdrwS
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.