Ad

Changing Style Object At Index Of Array In State In React

- 1 answer

i'm trying to update a style object inside my options array inside my apps state when an option is clicked in another component using toggleSelected (). Does anyone know how to best access the object and set the background color to something different?

App.js

this.state = {
    options: [
      {
        id: 0,
        label: "Industrial Truck and Tractor Operators",
        value: "53-7051",
        style: {
          display: "flex",
          margin: "auto",
          paddingTop: "1em",
          paddingBottom: "1em",
          paddingLeft: "1em",
          borderBottom: "solid",
          borderColor: "black",
          borderWidth: ".1em",
          color: "#64bd9a",
          backgroundColor: "white"
        },
        tooltip_text:
          'Operate industrial trucks or tractors equipped to move materials around a warehouse, storage yard, factory, construction site, or similar location. Excludes “Logging Equipment Operators" (45-4022).'
      },
      {
        id: 1,
        label: "Order Clerks",
        value: "43-4151",
        style: {
          display: "flex",
          margin: "auto",
          paddingTop: "1em",
          paddingBottom: "1em",
          paddingLeft: "1em",
          borderBottom: "solid",
          borderColor: "black",
          borderWidth: ".1em",
          color: "#64bd9a",
          backgroundColor: "white"
        },
        tooltip_text:
          'Receive and process incoming orders for materials, merchandise, classified ads, or services such as repairs, installations, or rental of facilities. Generally receives orders via mail, phone, fax, or other electronic means. Duties include informing customers of receipt, prices, shipping dates, and delays; preparing contracts; and handling complaints. Excludes "Dispatchers, Except Police, Fire, and Ambulance" (43-5032) who both dispatch and take orders for services.'
      }
    ],
    value: null,
    styles: {
      //container style is working
      marginTop: "2em",
      marginLeft: "2em",
      borderStyle: "solid",
      borderWidth: ".1em",
      borderBottom: "none",
      borderRight: "solid",
      width: "19em",
      textAlign: "justify",
      backgroundColor: "white",
      boxShadow: "3px 6px 5px #9E9E9E"
    },
    className: "",
    selectedClassName: "",
    loading_State: true, //this changes to false when the component loads
    childrenCount: 0
  };

  toggleSelected = child => {
    this.setProps({options.indexOf('1').style.backgroundColor: "gray" })
  };

Component.js

render() {
    return (
      <div style={this.props.styles}>
        {this.props.options.map(option => (
          <div
            key={option}
            id={"option" + option.id}
            style={option.style}
            onClick={e => {
              if (this.props.setProps) {
                this.props.setProps({ value: e.target.value });
              } else {
                this.setState({ value: e.target.value });
              }
              this.props.toggleSelected(option.id); //passing my index here to the function
            }}
          >
            <span id={option.id}> {option.label} </span>
            <UncontrolledTooltip
              placement="right"
              target={"option" + option.id}
            >
              {option.tooltip_text}
            </UncontrolledTooltip>
          </div>
        ))}
      </div>
    );
  }

Am I going about this the right way in terms of updating the styles object here. Should I use a different approach. Also I would like to do this without using CSS so adding classNames is not what I want to do.

Ad

Answer

I believe the following should work, assuming childIndex here represents the index of the state.options array that you want to modify.

toggleSelected = (childIndex) => {
  const newOptions = this.state.options.map((option, i) => {
    if (i !== childIndex) {
      return option;
    }
    return {
      ...option,
      style: {
        ...option.style,
        backgroundColor: "green" // your color here
      }
    }
  });

  this.setState({ options: newOptions });
}

Edit: If you need to change all the other colors to white, you can do the following:

toggleSelected = (childIndex) => {
  const newOptions = this.state.options.map((option, i) => {
    return {
      ...option,
      style: {
        ...option.style,
        backgroundColor: i === childIndex ? "green" : "white"
      }
    }
  });

  this.setState({ options: newOptions });
}
Ad
source: stackoverflow.com
Ad