Stefan Avramovic
Stefan Avramovic

Reputation: 1353

Close div in all child components

What i am trying to do is this: i have multiple child components, when i click on details i want to hide the same div in other child components

for example when i click on div 1 close 2 and 3 and so on

<div onClick="showDetails()">component 1</div>
<div onClick="showDetails()">component 2</div>
<div onClick="showDetails()">component 3</div>
<details></details>

I have tried using ref, but ref did not work it only closes the first component div..

 export default class Parent extends Component {

                  constructor(props) {
                    super(props)
                    this.myRef = React.createRef();         
                    this.handleActivity = this.handleActivity.bind(this)
                  }
                 handleActivity() {
                    //call to a method in Child component 
                    this.myRef.current.closeAll()
                 }

                  render() {
                    return (
                      <div>
                            <Child ref={this.myRef} closeAllOather={this.handleActivity} />
                            <Child ref={this.myRef} closeAllOather={this.handleActivity} />
                            <Child ref={this.myRef} closeAllOather={this.handleActivity} />
                            <Child ref={this.myRef} closeAllOather={this.handleActivity} />
                      </div>
                    )
                  }
                }

    export default class Child extends Component {
      constructor(props) {
        super(props)

        this.state = {
          show: false,
        }

        this.show = this.show.bind(this)
        this.hide = this.hide.bind(this)
      }

      closeAll(){
        this.setState({show: false})
           }

       show() {

        this.props.closeAllOather()
        this.setState({ show: true })
      }
      hide() {
        this.setState({ show: false })
      }

      render() {
        return (
          <div>
            <div onClick={this.show} />
            <div style={this.state.show ? visible : hidden}>
              <div style={detailBlock}>
                <span style={{ float: 'right' }} onClick={this.hide}>
                  close
                </span>

                {this.props.text}
                <br />
              </div>
            </div>
          </div>
        )
      }
    }

Any suggestion on how this can be done?

Upvotes: 1

Views: 141

Answers (2)

Evghenii
Evghenii

Reputation: 245

I would keep the currentElement in Parent and verify in Child if it's active.

Example:

class Parent extends React.Component {

  constructor(props) {
    super(props)

        this.state = {
      activeElement: null
    };

    this.onChildClick = this.onChildClick.bind(this)
  }

  onChildClick(e) {
    this.setState({activeElement: e.currentTarget});
  }

  render() {
    return (
      <div>
        <Child onClick={this.onChildClick} activeElement={this.state.activeElement} />
        <Child onClick={this.onChildClick} activeElement={this.state.activeElement} />
        <Child onClick={this.onChildClick} activeElement={this.state.activeElement} />
        <Child onClick={this.onChildClick} activeElement={this.state.activeElement} />
      </div>
    )
  }
}

class Child extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  render() {
    const isActive = this.myRef.current && this.myRef.current === this.props.activeElement;

    return (
      <div ref={this.myRef} style={{color: isActive ? 'red' : 'black'}} onClick={this.props.onClick}>Child</div>
    )
  }
}

https://jsfiddle.net/n7y9buqg/5/

Upvotes: 1

akshay kishore
akshay kishore

Reputation: 1027

Change handleActivity in the Parent to

 handleActivity(id) {
                    this.setState({
                       selectedChild:id
                    });
                 }

and the render in the parent to

render() {
                    return (
                      <div>
                            <Child isSelected={this.state.selectedChild === 1 ? "true":"false"} ref={this.myRef} closeAllOather={this.handleActivity(1)} />
                            <Child isSelected={this.state.selectedChild === 2 ? "true":"false"} ref={this.myRef} closeAllOather={this.handleActivity(2)} />
                            <Child ref={this.myRef} isSelected={this.state.selectedChild === 3 ? "true":"false"} closeAllOather={this.handleActivity(3)} />
                            <Child ref={this.myRef} isSelected={this.state.selectedChild === 4 ? "true":"false"} closeAllOather={this.handleActivity(4)} />
                      </div>
                    )
          }

Finally in the child do:

render() {
        return (
          <div>
            <div onClick={this.show} />
            <div style={this.state.show ? visible : hidden}>
              <div style={this.props.isSelected === "true" ? detailBlock:{display: "none"}}>
                <span style={{ float: 'right' }} onClick={this.hide}>
                  close
                </span>

                {this.props.text}
                <br />
              </div>
            </div>
          </div>
        )
      }

Upvotes: 0

Related Questions