-1

I am new to React and am unable to find a solution in other posts related to my problem.

I am building a simple page which displays a set of four radio inputs to select the type of user to be registered. The problem lies with the handling of the states I believe.

import React, { Component/*, useEffect*/ } from 'react'


export default class CreateUser extends Component {
  
  constructor(props) {
    super(props);
    this.state = {
      clasificacion: "",
      rol: ""
    };
  }
  setClasificacionRadio = (e) => {
    console.log(e.currentTarget);
    this.setState({clasificacion: e.currentTarget.value}, 
      ()=>{
        console.log("clasificacion: "+this.state.clasificacion);
      }
    );    
  }
  setRolRadio = (e) => {
    console.log(e.currentTarget);
    this.setState({rol: e.currentTarget.value}, 
      ()=>{
        console.log("Rol: "+this.state.rol);
      }
    );
  }
  render() {
    return (
      <div className="container">
        <div className="row mt-3">
          <div className="col-12 col-md-12">
            <h3 className="text-center font-weight-bold">Registro de Usuarios</h3>
          </div>           
        </div>
        <div className="row mt-5">
          <div className="col-12 col-md-12">
            <h4 className="text-center font-weight-bold">Seleccione la Clasificación del Usuario</h4>
          </div>           
        </div>
        <div className="row mt-2">
          <div className="col-12 col-md-6 offset-md-3">
            <div className="input-append">
              <div className="btn-group pull-left" data-toggle="buttons">
                <label className="">Empleado</label>
                  <input type="radio" name="clasif" className='form-check' value="btn1"
                    onChange={this.setClasificacionRadio} 
                    checked={this.state.clasificacion === "btn1"}
                    style={{marginTop: 15, marginLeft: 5, marginRight: 20}}
                  />
                <label className="">Institución</label>
                  <input type="radio" name="clasif" className='form-check' value="btn2"
                    onChange={this.setClasificacionRadio} 
                    checked={this.state.clasificacion === "btn2"}
                    style={{marginTop: 15, marginLeft: 5, marginRight: 20}}
                  />

                <label className="">Socio</label>
                  <input type="radio" name="clasif" className='form-check' value="btn3"
                    onChange={this.setClasificacionRadio} 
                    checked={this.state.clasificacion === "btn3"}
                    style={{marginTop: 15, marginLeft: 5, marginRight: 20}}
                  />

                <label className="">Obra Social</label>
                  <input type="radio" name="clasif" className='form-check' value="btn4"
                    onChange={this.setClasificacionRadio} 
                    checked={this.state.clasificacion === "btn4"}
                    style={{marginTop: 15, marginLeft: 5, marginRight: 20}}
                  />
              
              </div>
            </div>
          </div>           
        </div>
        <div className="row mt-5">
          <div className="col-12 col-md-12">
            <h4 className="text-center font-weight-bold">Seleccione el Rol del Usuario a Crear</h4>
          </div>           
        </div>
        <div className="row mt-2">
          <div className="col-12 col-md-6 offset-md-3">
            <div className="input-append">
              <div className="btn-group pull-left" data-toggle="buttons">
                <label className="">Administrador</label>
                  <input type="radio" name="rol" className='form-check' value="ROL1"
                    onChange={this.setRolRadio} 
                    checked={this.state.rol === "ROL1"}
                    style={{marginTop: 15, marginLeft: 5, marginRight: 20}}
                  />
                <label className="">Facturador</label>
                  <input type="radio" name="rol" className='form-check' value="ROL2"
                    onChange={this.setRolRadio} 
                    checked={this.state.rol === "ROL2"}
                    style={{marginTop: 15, marginLeft: 5, marginRight: 20}}
                  />

                <label className="">Usuario de Carga</label>
                  <input type="radio" name="rol" className='form-check' value="ROL3"
                    onChange={this.setRolRadio} 
                    checked={this.state.rol === "ROL3"}
                    style={{marginTop: 15, marginLeft: 5, marginRight: 20}}
                  />
              
              </div>
            </div>
          </div>           
        </div>
        <div className="row mt-5">
          <div className="col-12 col-md-4 offset-md-4">
            <button id="" className="btn btn-outline-dark btn-block">
              Continuar
            </button>
          </div>
        </div>
      </div>
    )
  }
}

console log of states

Even though the state changes, the radio button's checked property remains unchanged so the radio buttons are never selected.

EDIT

Updated to place the switch inside the setState callback so it shows the state changes correctly as suggested by @Dhruvi Makvana

The problem remains, the radio buttons stay unselected but clicking on them show state changes in the console.

EDIT 2

I added a second row of 4 radio buttons with it's own comparison, state and function. I realized the first row's radio buttons are beeing updated only when I click a radio button from the second row and viceversa, also realized the checked atribute is not beeing updated accordingly to the asynchronous call from the setState. The code above has been updated to show these changes.

At this point I'm thinking I should perhaps change the title of this post?, suggestions?.

EDIT 3

I ran the updated code in a sandbox as @Vimal Patel did, it runs well, I don't know how to debug this issue. Sandbox: https://codesandbox.io/s/stupefied-jennings-sxbfn

Sulfur0
  • 39
  • 7

1 Answers1

1

this.setState() is asynchronous, which means it doesn't guarantee an updated state in the next line. Try moving the switch case in another function or put it in setState callback.

Dhruvi Makvana
  • 895
  • 5
  • 17
  • Yes, I corrected the switch by placing it at the callback of the setState, it now shows the state updates at the moment, the problem remains tho, I can see the states changing in the console but the radio buttons won't change its checked property. – Sulfur0 Oct 29 '20 at 15:48
  • can you try changing values to "btn1", "btn2".. and comparison respectively . – Dhruvi Makvana Oct 29 '20 at 16:16
  • So initially after changing radio's values to "btn-1", "btn2".. as suggested, nothing changed, but then I tried something, I added a second row of 4 radio buttons with it's own comparison, state and function. I realized the first row is not changing the checked property by its own, I need click some radio from the second row so the checked properties update. I will update my code with the changes. This shouln't be this hard. – Sulfur0 Oct 29 '20 at 17:45