Reputation: 1353
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
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
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