0

I'm trying to build a section in my web page where there are four components displayed in a 2X2 grid. When you click one, the box expands to the center of the screen while the others fade out. I've got that part figured out by calling setState on a few different properties to toggle css classes.

What I'm having trouble with is resetting the state when a "close" button is kicked so that the boxes assume their original shape and opacity. I'm seeing a console.log from within the "handleCloseClick" function, so I know that it is wired property. No matter how I loop through the array of the state, I cannot change their properties back to their original state. Here's my code.

class Parent extends Component{
  constructor(){
    super();
    this.state = 
      attrs: {[{
        id: 1,
        expand: false,
        reduced: false,
        seeText: false
    }],
    [{
        id: 2,
        expand: false,
        reduced: false,
        seeText: false
    }],
    [{
        id: 3,
        expand: false,
        reduced: false,
        seeText: false
    }],
    [{
        id: 4
        expand: false,
        reduced: false,
        seeText: false
    }]}
    this.handleClick = this.handleClick.bind(this)
    this.handleCloseClick = this.handleClick.bind(this)
  }
  /*This function works*/
  handleClick(e){
    const array = this.state.attrs
    array.map(function(element){
      if(element.id === i){
        element.reduced = false;
        element.expand = true;
        element.seeText = true;
      }else{
        element.reduced = true;
      }
    })
    this.seState({attrs: array})
  }
  /*This function will console.log but will not setState of attrs*/
  handleCloseClick(){
    const newArray = this.state.attrs
    newArray.map(function(element(){
      element.expand = false;
      element.reduced = false;
      element.seeText = false;
    })
    this.setState(attrs: newArray})
  }
  render(){
    const newEls = this.state.attrs;
    return(
      {newEls.map(function(newEl, index)){
        return <Child key={index} onClick={this.handleClick(el)} onCloseClick={this.handleCloseClick()} />
      }
    )
  }
}

Please help! Why won't the damn state change back?!?!

Ian Springer
  • 223
  • 2
  • 7
  • 19
  • There is a syntax error in your `newArray.map(function(element(){ element.expand = false; element.reduced = false; element.seeText = false; })` and should be `newArray.map(function(element){ element.expand = false; element.reduced = false; element.seeText = false; })` – Tharaka Wijebandara Apr 22 '17 at 04:06

1 Answers1

1

There's a few issues... .map returns a new array, it doesn't change the existing state. So you need to assign it to a variable to see the changes.

Also, you have to return a value in .map, or use an "implicit" return({ vs {.

handleCloseClick(){
  const newArray = this.state.attrs.map(element => ({
    element.expand = false;
    element.reduced = false;
    element.seeText = false;
  }))
  this.setState(attrs: newArray})
}

You can also move initial state into its own method, then use in the constructor and when you want to reset it...

  constructor() {
  ...
    this.state = this.initialState();
  }
  
  close() {
    this.setState(this.initialState());
  }
  
  initialState() {
    return {
      attrs: [
      [{
          id: 1,
          expand: false,
          reduced: false,
          seeText: false
      }],
      [{
          id: 2,
          expand: false,
          reduced: false,
          seeText: false
      }],
      [{
          id: 3,
          expand: false,
          reduced: false,
          seeText: false
      }],
      [{
          id: 4
          expand: false,
          reduced: false,
          seeText: false
      }]}
    ]}
  }
Community
  • 1
  • 1
BradByte
  • 11,015
  • 2
  • 37
  • 41