Tyler Clay
Tyler Clay

Reputation: 13

How do I limit the user to only selecting one component?

I have the following code that simply constructs blocks for our products and the selected state allows the component to be selected and unselected. How can I figure out which of these components are selected and limit the user to only selecting one at a time. This is ReactJS code

import React from 'react';

export default class singleTile extends React.Component{

constructor(props){
  super(props);
  this.title = this.props.title;
  this.desc = this.props.desc;
  this.svg = this.props.svg;
  this.id = this.props.id;
  this.state = {
    selected: false
  }
}
selectIndustry = (event) => {
    console.log(event.currentTarget.id);
    if(this.state.selected === false){
      this.setState({
        selected:true
      })
    }
    else{
      this.setState({
        selected:false
      })
    }

}


render(){
return(
    <div id={this.id} onClick={this.selectIndustry}className={this.state.selected ? 'activated': ''}>
          <div className="icon-container" >
            <div>
              {/*?xml version="1.0" encoding="UTF-8"?*/}
              { this.props.svg }
            </div>
          </div>
          <div className="text-container">
            <h2>{this.title}</h2>
            <span>{this.desc}</span>
          </div>
        </div>
    )
}

}

Upvotes: 0

Views: 71

Answers (2)

Donny Verduijn
Donny Verduijn

Reputation: 444

You need to manage the state of the SingleTile components in the parent component. What i would do is pass two props to the SingleTile components. A onClick prop which accepts a function and a isSelected prop that accepts a boolean. Your parent component would look something like this.

IndustrySelector.js

import React from 'react';

const tileData = [{ id: 1, title: 'foo' }, { id: 2, title: 'bar' }];

class IndustrySelector extends Component {

    constructor(props) {
        super(props);
        this.state = { selectedIndustry: null };
    }

    selectIndustry(id) {
        this.setState({ selectedIndustry: id });
    }

    isIndustrySelected(id) {
        return id === this.state.selectedIndustry;
    }

    render() {
        return (
        <div>
            {tileData.map((data, key) => (
            <SingleTile
                key={key}
                {...data}
                onClick={() => this.selectIndustry(data.id)}
                isSelected={this.isIndustrySelected(data.id)}
            />
            ))}
        </div>
        );
    }
}

The way this works is as follows.

1. Triggering the onClick handler

When a user clicks on an element in SingleTile which triggers the function from the onClick prop, this.selectIndustry in the parent component will be called with the id from the SingleTile component.

Please note that in this example, the id is remembered through a closure. You could also pass the id as an argument to the function of the onClick prop.

2. Setting the state in the parent component

When this.selectIndustry is called it changes the selectedIndustry key of the parent component state.

3. Updating the isSelected values form the SIngleTile components

React will automatically re-render the SingleTile components when the state of the parent component changes. By calling this.isIndustrySelected with the id of the SingleTile component, we compare the id with the id that we have stored in the state. This will thus only be equal for the SingleTile that has been clicked for the last time.

Upvotes: 1

Bruinen
Bruinen

Reputation: 109

Can you post your parent component code?

It's not so important, but you can save some time by using this ES6 feature:

constructor(props){
    super(props);
    const {title, desc, svg, id, state} = this.props;
    this.state = {
      selected: false
  }
}

Upvotes: 0

Related Questions