Home > Software design >  Switching classes between items from the list in React
Switching classes between items from the list in React

Time:10-17

im doing this simple ecommerce site, and on the product page you have different attributes you can choose, like sizes, colors - represented by clickable divs, with data fetched from GraphQl and then generated to the DOM through map function.

return (
      <div className="attribute-container">
        <div className="attribute">{attribute.id.toUpperCase()}:</div>
        <div className="attribute-buttons">
          {attribute.items.map((item) => {
            if (type === "Color") {
              return (
                <AttributeButton
                  key={item.id}
                  className="color-button"
                  style={{ backgroundColor: item.value }}
                  onClick={() => addAtribute({type: type, value: item.value })}/>

              );
            }
            return (
              <AttributeButton
                key={item.id}
                className="size-button"
                size={item.value}
                onClick={() => addAtribute({ type: type, value: item.value })}
              />
            );
          })}
        </div>
      </div>
    );

Im importing external component, then I check if an attribute's type is Color (type color has different styling), then render depending on that type.

What I want to implement is that when i click on one attribute button, its style changes, BUT of course when i click on another one, choose different size or color for the item i want to buy, new button's style changes AND previously selected button goes back to it's default style. Doing the first step where buttons style changes onClick is simple, but i cant wrap my head around switching between them when choosing different attributes, so only one button at the time can appear clicked.

Here is code for AttributeButton:

class Button extends PureComponent {

  constructor(props){
    super(props);
    this.state = {
      selected: false,
    }
  }

  render() {
    return (
      <div
        className={ !this.state.selected ? this.props.className : "size-selected " this.props.className}
        style={this.props.style}
        onClick={() => {this.props.onClick(); this.setState({selected: !this.state.selected}) }}
      >
        {this.props.size}
      </div>
    );
  }
}

export default Button;

PS - i have to use class components for this one, it was not my choice.

CodePudding user response:

You need to have the state selected outside of your <Button> component and use it as a prop instead. Something like:

handleSelect = (button) => {
  const isSelected = this.state.selected === button;
  this.setState({ selected: isSelected ? false : button });
};

render() {
  return (
    <>
      <Button
        isSelected={this.state.selected === "ColorButton"}
        onClick={() => this.handleSelect("ColorButton")}
      />

      <Button
        isSelected={this.state.selected === "SizeButton"}
        onClick={() => this.handleSelect("SizeButton")}
      />
    </>
  );
}
  • Related