Issue with this.setState() not updating value despite not being related to asynchronous updates

Just a quick note, this specific question does not involve any asynchronous update problem (at least, as far as I can tell).

I currently have a class component with the following code snippet (simplified for clarity on the main issue):

  constructor(props) {
     super(props);
     this.state = {
       aSelected: false;
       bSelected: false
     }
  }

 handleCheckboxChange = (e) => {   
     const { checked, value } = e.target;
    
     console.log( 'checked: ', checked );

     if(value=="a") {
        this.setState( {aSelected: checked}, () =>  {
        console.log('aSelected: ', this.state.aSelected);
        console.log("----")
     });
     }

     if(value=="b") {
        this.setState( {bSelected: checked}, () =>  {
        console.log('bSelected: ', this.state.bSelected);
        console.log("----")
        
     });
     } 
 }

Within the render return section, I've included the following:

<input>
   type="checkbox"
   value="a"
   onChange={this.handleCheckboxChange}
   checked={this.state.aSelected}
   disabled={ (this.state.aSelected || (!this.state.aSelected && !this.state.bSelected) ) ? false : true} 
</input>

<input>
   type="checkbox"
   value="b"
   onChange={this.handleCheckboxChange}
   checked={this.state.bSelected}
   disabled={ (this.state.bSelected || (!this.state.aSelected && !this.state.bSelected) ) ? false : true}
</input>

The output recorded in Chrome Developer Tools displays how the "checked" status changes accordingly when selecting and deselecting checkboxes. Nevertheless, the state of "selected" (should be "aSelected") remains unaltered and retains its initial false value. Any insights into why "selected" (should be "aSelected") is not updating?

Edit: The task I'm aiming to achieve involves two checkbox items where the user can only choose ONE or none at all. If one is selected, the other should be disabled.

https://i.stack.imgur.com/51WU2.png

Answer №1

Whenever you update the state by calling setState in React, the component is re-rendered and the checkbox goes back to its default unchecked state.

To effectively manage the checkbox state, make sure to use the current state. Your JSX structure should resemble this:

<input
   type="checkbox"
   checked={this.state.aSelected}
   onChange={this.handleCheckboxChange}
/>

In React's terminology, this falls under a "controlled component" category as React handles all changes to the input state. For further information, refer to the documentation here: https://reactjs.org/docs/forms.html#controlled-components or https://reactjs.org/docs/uncontrolled-components.html

Revision for Question Adjustments: Ensure that in your render function, you are using this.state.aSlected. Additionally, do not forget to include the checked={this.state.aChecked} attribute, or else the checkbox will remain unchecked upon the next rendering. For example:

<input
   type="checkbox"
   value="a"
   onChange={this.handleCheckboxChange}
   checked={this.state.aSelected}
   // added for clarification *
   disabled={this.state.aSelected || (!this.state.aSelected && !this.state.bSelected) ? false : true} 
/>

Revise with Functional Example Here is an interactive CodeSandbox demonstration showcasing how checking one checkbox disables the other:

class CheckboxComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      aSelected: false,
      bSelected: false
    };
  }

  handleCheckbox = (event) => {
    if (event.target.name === "boxA") {
      this.setState({ aSelected: event.target.checked });
    } else if (event.target.name === "boxB") {
      this.setState({ bSelected: event.target.checked });
    }
  };

  render() {
    let aDisabled = this.state.bSelected && !this.state.aSelected;
    let bDisabled = this.state.aSelected && !this.state.bSelected;

    return (
      <div>
        <label>
          <input
            type="checkbox"
            name="boxA"
            checked={this.state.aSelected}
            onChange={this.handleCheckbox}
            disabled={aDisabled}
          />
          Checkbox A
        </label>
        <br />
        <br />
        <label>
          <input
            type="checkbox"
            name="boxB"
            checked={this.state.bSelected}
            onChange={this.handleCheckbox}
            disabled={bDisabled}
          />
          Checkbox B
        </label>
      </div>
    );
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for extracting the two characters following a space in a string with or without the use of regex

How can I extract only the initials of 2 characters after spaces? See the code snippet below: const name = "John Peter Don"; const result = name.match(/\b(\w)/g).join(''); console.log(result)// JPD->> i want only JP ...

Unlocking the ability to retrieve data generated by the context within getServerSideProps beyond its boundaries (for transitioning from Create React App to Next.js)

I am currently utilizing Create React App for my react application but I am in the process of migrating to Next.js. Accessing URL data such as host, protocol, and query parameters has posed a significant challenge. After some trial and error, I realized t ...

When a named capture group is included in the regex of a GET path, Express crashes with the error message: "Cannot read property 'name' of undefined at Layer

I am looking to process a GET request and extract specific information from the URL. Let's consider this scenario: const REGEX_QUERY = /^\/?house\/(?<street>[a-z]+)\/(?<house>[0-9]+)$/i; const REGEX_QUERY_NO_NAMES = /^\ ...

Can two writable stores in Svelte be set up to subscribe to each other simultaneously?

There is a unique scenario where two objects share data, yet have different structures. For instance, the 'Team' object has the team ID as its key. The 'Team' object includes 'name' and 'users' objects as its values ...

NodeJS buffer is not capable of handling incomplete TCP stream data

While troubleshooting my TCP JSON stream on the live server, I discovered that if the data streamed to me in JSON format is excessive, it doesn't consistently parse correctly. It requires multiple streams for successful parsing. Here is the code I am ...

Is there a way to change a mandatory field to optional in SuiteCRM?

I have two fields, field-A and field-B. The behavior of field-B depends on the value selected in field-A. If field-A has a value of 1, then field-B becomes a required field. To achieve this, I utilize SuiteCRM's addToValidate JavaScript function. How ...

Exploiting the Power of useRef with TypeScript in Functional Components of React

I'm having trouble accessing the child component method from the parent component using useRef. Eventually, the SayHi method will be responsible for updating the hook state in the child component. Unfortunately, I am encountering some bugs that I can ...

Troubleshooting problem with populating data in Mongoose Database

Here is the code snippet: app.get("/cart", checkAuthentication, function (req, res) { Orders.find({ user: req.user._id }) .populate('user') .populate('order') .exec((err, orders) => { console.log(orders); ...

The route path seems to be malfunctioning as I attempted to display chats based on the roomId, but it is not functioning correctly

Can someone help me with rendering chats based on the Room ID? I've tried using the URL but my chat component doesn't show up on the screen. I attempted to use the exact path method as a potential solution. Below is a snippet of my router path co ...

Set up an event listener for when geolocation permission is approved

My Setup: I've written some basic code snippet below: const onSuccess = () => { console.log('success'); } const onError = () => { console.log('error'); } navigator.geolocation.getCurrentPosition(onSuccess, onError) ...

Parse multiple JSON files, manipulate their contents, and store the updated data

I'm currently working on implementing this functionality using Gulp. Locate and access all files with the extension .json within a designated directory, including any subdirectories. Perform modifications to the files in some manner, such as adding ...

Next js is throwing an error because it cannot accept objects as a React child. Instead, it found an error message stating "Response not successful: Received status code 401."

This app showcases Github issues by utilizing the graphql API. After finishing the app, I encountered an error without making any changes. The technologies used for this project include Next.js, Typescript, Material UI, Tailwind CSS, and GraphQL. https: ...

Difficulty with CasperJS multi-select functionality

I am currently attempting to utilize CasperJS for choosing both options in a multiple select within an HTML form: <select id="bldgs" name="bldgs" multiple="multiple" size="6" autocomplete="off"> <option value="249759290">Southeast Financia ...

What's the most efficient method for updating dependencies in various npm projects simultaneously?

As open-source library creators, especially those focused on React, it is common to have developed and released numerous React components. However, the process of upgrading each component to the latest version of React (e.g., v16) can be quite tedious. Is ...

Ways to reload a React webpage following error resolution

I am currently facing an issue with the code below: <ErrorBoundary> <NavBar /> </ErrorBoundary> <ErrorBoundary> <Switch> <Route exact path="/" component={mainPage} /> ...

The placement of Bootstrap Datepicker is experiencing issues

I have integrated the Bootstrap Datepicker from Eternicode into my ASP.Net MVC website. While the functionality is working well, I am facing difficulty in positioning the datepicker modal using the orientation option mentioned in the documentation and code ...

Limit the 'contenteditable' attribute in table data to accept only integers

I have a question regarding editing table data row. Is there a way to restrict it to only integers? Thank you for your assistance! <td contenteditable="true" class="product_rate"></td> ...

Ensure that parameters are validated correctly in the Next.JS application router using the searchParams method

When building the page, I need to properly validate params in the Next.JS app router using searchParams. My goal is to show a main image (coverImage) for each photo on the /gallery page. When a photo is clicked, I want to display more photos of the same k ...

Creating Vue components and including Javascript code within them

Attempting to develop a component using Vue for my JavaScript code, but encountering issues. My primary aim is to build a component with either Vue or Vue3 <head> <title></title> <script src="https://cdn.jsdelivr ...

Is there a way to include multiple TinyMCE editors with unique configurations for each one?

Is it possible to incorporate multiple TinyMCE editors on a single page, each with its own distinct configuration settings? If so, how can this be achieved? ...