Rishi Prasad
Rishi Prasad

Reputation: 69

Keeping track of selected div in grid of divs with React state

I am new to React/JS and have been trying for a few days to figure out how to keep track of which Collection below is selected.

I want the user to be able to click on the collection div and trigger the selected badge (commented out in the code, but I've included it in the screenshots) for that specific collection div. Upon clicking on a new div, the original div should have the badge remove and the newly clicked upon div should have the new badge. In other words, only one collection should have the badge at any point in time. I want to keep track of this in the Collection component's state (unless there is a better way).

For more reference, each collection div is a card that is highlighted upon hover. The site is also deployed at https://gatsby-client.rishipr.now.sh/practice.

CollectionList

Collection.js

import React, { Component } from "react"

class Collection extends Component {
  render() {
    return (
      <div className="collection">
        <div className="collection-name">
          {this.props.name}{" "}
          {/* <span className="collection-selected-badge">SELECTED</span> */}
        </div>
        <div className="collection-description">{this.props.description}</div>
        <div className="collection-description">
          {this.props.numQuestions} questions
        </div>
      </div>
    )
  }
}

export default Collection

CollectionList.js

import React from "react"
import Collection from "./collection"

const CollectionList = props => {
  return (
    <div className="collections">
      <Collection
        name="All Questions"
        description="All questions (technical & behavioral)"
        numQuestions="400"
      />
      <Collection
        name="Top Behavioral"
        description="The most common behavioral questions to prepare for"
        numQuestions="21"
      />
      <Collection
        name="Outside the Guide"
        description="Questions from outside BIWS 400 and WSO"
        numQuestions="12"
      />
      <Collection
        name="20 Must Know Questions"
        description="The 20 must-know interview questions"
        numQuestions="20"
      />
      <Collection
        name="Real IB Interview Questions"
        description="Questions from real interviews at various banks"
        numQuestions="16"
      />
      <Collection
        name="Brain Teasers"
        description="Common brain teasers"
        numQuestions="4"
      />
    </div>
  )
}

export default CollectionList

Upvotes: 2

Views: 2229

Answers (1)

Istvan Szasz
Istvan Szasz

Reputation: 1567

Add state to your CollectionList component, storing the name of the selected Collection:

const CollectionList = props => {
  const [selected, setSelected] = useState(null);
  return (
  // ...
  )
}

Pass the selected and setSelected props to all of your Collection component:

<Collection
  name="All Questions"
  description="All questions (technical & behavioral)"
  numQuestions="400"
  selected={selected}
  setSelected={setSelected}
/>

Add an onClick method to the outer div of your Collection component, which sets the selected state value to the name of the current Collection:

<div
  className="collection"
  onClick={() => this.props.setSelected(this.props.name)}
>
  // ...
</div>

Check if the selected prop is the same as the current collection's name in your Collection component. If true display the selected badge:

{this.props.selected === this.props.name && (
  <span className="collection-selected-badge">SELECTED</span>
)}

Here's a codesandbox example, though not as pretty as the image you provided.

Upvotes: 1

Related Questions