Tony
Tony

Reputation: 489

Hide or display targeted elements, after mapping, in React (functional components)

I fetched some data in React with axios and so far everything is displayed as it should. The problem is that when I click on a Header, the content below the header should be displeyd (or get hidden). So far I managed to do this but it works on all the fetched items. How I target a specific item after mapping? The code is as below:

const BlogItems = () => {
const [blogList, setBlogList] = useState([])
const [err,setErr] = useState("")
const [show, setShow] = useState(false)


const ClickHandle = (e)=>{
    setShow(!show)
}

useEffect(()=>{
    const blogFetch = async ()=>{
            const response = await axios.get(url)
            setBlogList(response.data.sheetData)
}
    
    blogFetch()
}, []);


const renderedBlogItems = 
blogList.map((item)=>{
    return( 
        <div key={item.ID} id={item.ID} className="ui container segment">
            <div className="ui items">
                <div className="item">
                    <div className="image">
                        <img src={item.Image} />
                    </div>
                    <div className="content">
                        <a className="header"  onClick = {ClickHandle}>{item.Header}</a>
                        <div className="meta">
                            <span>{item.Date}</span>
                        </div>
                    </div>
                </div>               
            </div>
            {
                show ? <div dangerouslySetInnerHTML={{ __html: item.Content}} ></div> : null
                }
        </div>
            
    )

}).reverse()


return (
    
       blogList.length<1 ?  <div className="ui active dimmer"> <div className="ui text loader">Loading Blog Posts...</div> </div> : <div className="ui raised  padded  container segment"> {renderedBlogItems} </div> 
   
)

}

Upvotes: 0

Views: 62

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370999

Either use an array of state for each blogList item (instead of just a boolean), or - probably better - use a separate component for each item, and use state in that instead, so each item corresponds to a separate component with its own state:

blogList.map((item, i) => <BlogItem item={item} key={i} />)
const BlogItem = ({ item }) => {
  const [show, setShow] = useState(false);
  const ClickHandle = (e)=>{
    setShow(!show)
  };
  return (
    <div key={item.ID} id={item.ID} className="ui container segment">
      <div className="ui items">
      // etc
};

Upvotes: 1

Related Questions