1

I need to change the state of sibling components in my React App. I use state and setstate

I need to change the state of sibling components. When loading the page, there must exist (visible in the page) <BkUser /> and when clicking "button id =" ds-visual "it must be deleted (<BkUser /> mustn't exist) and there must exist <BkDescanso />. When you click on <BkSleep /> (in the div parent) you should remove <BkDescanso /> and show <BkUser />

This is the web. There should never be <BkUser/> and <BkSleep> at the same time. <Bkuser /> is the blue block and <BkDescanso /> is the red block

This is my code:

Edit: I edit my original code because I fix the problem. This is the final OK Code. In the end the most important thing was the state conditional

{
this.state.usuario ? (<BkUser handleClick = {this.handleClick} usuario={this.state.usuario}/>): (<BkDescanso handleClick = {this.handleClick} usuario={this.state.usuario}/>)}
import React, { Component } from 'react';

class Header extends Component {
    constructor(props) {
        super(props);

        this.state = {
            usuario: true,
        };

        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState(state => ({
          usuario: !state.usuario
        }));
        //alert("Works button");
      }

    render(){
        return (
            <header className="header">
                <div className="configuracion">
                {
          this.state.usuario
            ? (
                <BkUser handleClick = {this.handleClick} usuario={this.state.usuario}/>
            )
            : (
                <BkDescanso handleClick = {this.handleClick} usuario={this.state.usuario}/>
                )}
                    <div className="content-btn">
                        <button id="config" className='btn btn--rounded'><span className="ico-configuracion"></span></button>
                        <button id="salir" className='btn btn--rounded'><span className="ico-exit"></span></button>
                    </div>
                </div>
            </header>
        );
    }
}

class BkUser extends Component{

    render(){
            return ((    
                <div className='usuario'>
                    <img src="../img//usuario.svg" alt="Imagen usuario"/>
                    <div className="content-usuario">
                        <span id="nm-usuario" className="h4">Hermione Jane Granger</span>
                        <span id="tp-usuario" className="h5">Supervisor</span>
                    </div>
                    <div className="content-descansos">
                        <div className="botones">
                            <button id="ds-visual" className='btn btn--rounded' onClick={this.props.handleClick}><span className="ico-visual"></span></button>
                            <button id="ds-admin" className='btn btn--rounded'><span className="ico-tiempo-administrativo"></span></button>
                            <button id="ds-otros" className='btn btn--rounded'><span className="ico-descanso"></span></button>
                        </div>
                        <div className="ds-actual">
                            <span id="ds-tipo">Administrativo</span>
                            <span id="ds-tiempo">00:08:47</span>
                        </div>
                    </div>
                </div>
            ));
    }
}

class BkDescanso extends Component {

    render(){
        return ((   
            <div className='usuario descanso' onClick={this.props.handleClick}>
                <h3>Finalizar descanso</h3>
            </div>
        ));
    }
}


export default Header;

Right now handleClick works but always exist BkUser and BkDescanso. I need only one to exist. If you click on id = "ds-visual" the bkUser block should disappear and BkDescanso appear. Then if you click on div className = 'user rest' in BkUser there should only be BkDescanso.

I think that it is not able to know when it is true and when it is false to show or hide

Thanks a lot for the help.

Casandra
  • 161
  • 2
  • 13
  • 1
    It's better if you handle your childs state data in to parent component. So whenever you click a button in child then just call a function using this.props.functionName in parent and update state in parent that will cause rerender of whole component. – Amit Chauhan Apr 12 '19 at 08:06

2 Answers2

1

You're missing two things:

First you have to pass the handleClick function to the BkUser component, and then you have to call it via this.props.handleClick.

...
<BkUser handleClick={this.handleClick} usuario={this.state.usuario} />
....
<button
    id="ds-visual"
    className="btn btn--rounded"
    onClick={this.props.handleClick}
    >
    ds-visual
    <span className="ico-visual" />
</button>

CodeSandbox here.

Read more here.

sanjsanj
  • 1,003
  • 9
  • 20
  • Thanks a lot! Right now handleClick works but always exist BkUser and BkDescanso. I need only one to exist. If you click on id = "ds-visual" the bkUser block should disappear and BkDescanso appear. Then if you click on div className = 'user rest' in BkUser there should only be BkDescanso. I edit with your changes. Thanks again. – Casandra Apr 12 '19 at 12:06
0

You can change the state of the siblings by passing a function from the parent via props into them.

In the end your siblings are the children of their parent.

You can read this articles on how to change the state of child components.

React js change child component's state from parent component

https://medium.freecodecamp.org/react-changing-state-of-child-component-from-parent-8ab547436271

An other thing you could look into would be React Redux.

Joshua Beckers
  • 857
  • 1
  • 11
  • 24
  • Thanks Jay Bee. I have tried to follow the steps of the url that you have recommended but it still does not work. – Casandra Apr 12 '19 at 07:43
  • What did you do and what was the result. Can you edit your question to clarify what you want to achieve exactly. In your following sentence is missing what you are expecting from your program: " When loading the page, there must be and when clicking "button id =" ds-visual "it must be deleted () and there must be . " – Joshua Beckers Apr 12 '19 at 08:25
  • I edif the question. I hope you understand it now. Sorry for my english. – Casandra Apr 12 '19 at 08:53