Issue with Material-UI Nested Checkbox causing parent DOM to not update upon selection changes

Currently, I am integrating a nested checkbox feature from a working example into my application. The functionality of the checkboxes covers seven different scenarios:

- Scenario - No children, no parent selected
  - Select the parent -> select both parent and all children
  - Select a child -> select that child and its parent
- Scenario - All children and the parent selected
  - Select the parent -> deselect the parent and all children
  - Select a child -> deselect only that child
- Scenario - Some children and the parent selected
  - Select the parent -> select all unselected children
  - Select a child -> select that child while keeping parent selected
  - Deselect last child -> deselect the child and parent

The challenge I'm facing is that when a child checkbox is selected or deselected, the state of the parent checkbox updates correctly but there's no visual change in the checkbox itself.

In my code snippet:

<Checkbox
  disableRipple
  edge="start"
  checked={sub.checked}
  onChange={() =>
    this.handleCheckClick(sub.id, parentIndex)
  }
/>

The Material-UI <Checkbox /> component is embedded within a list where each item has its own set of items with individual <Checkbox /> components. When I select the parent checkbox, the state changes as expected through the handleCheckClick() method, updating both state and visuals accordingly.

However, when clicking on a child checkbox, although the parent gets selected in the state, the visual update does not occur despite the checked state being linked to the state property.

An interesting observation is that using a native input like this:

<input
  type="checkbox"
  disableRipple
  edge="start"
  checked={sub.checked}
  onChange={() =>
    this.handleCheckClick(sub.id, parentIndex)
  }
/>

Displays the correct behavior visually and also maintains the state consistency. It's unclear if this discrepancy is specific to Material-UI, a race condition, or another issue, but the logic within the handleCheckClick() function seems sound since state changes reflect accurately.

Answer №1

There is actually a warning that provides insight into the issue at hand:

Warning: A component is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More information can be found here: https://reactjs.org/docs/forms.html#controlled-components

The main problem lies in the fact that the checked state is not initialized in createSubscriptions (refer to code snippet below), which results in sub.checked initially being undefined. This causes Material-UI to interpret the checkbox as uncontrolled, hence setting the checked state later on has no impact.

function createSubscriptions() {
  const statusSet = ["Processing", "Completed", "Submitted", "Error"];
  const quantity = (faker.random.number() % 10) + 1;
  const subscriptions = [];
  let x = 0;
  while (x < quantity) {
    subscriptions.push({
      id: faker.random.uuid(),
      name: faker.lorem.words(),
      description: faker.lorem.sentence(),
      created: faker.date.past(),
      status: statusSet[faker.random.number() % 4],
      checked: false, // INCLUDING THIS RESOLVES THE ISSUE
      geoJson: {
        features: createGeoJson()
      }
    });
    x += 1;
  }
  return subscriptions;
}

https://codesandbox.io/s/nested-checkboxs-material-ui-im5t8?fontsize=14

Alternatively, you can address this by handling it when rendering the Checkbox:

<Checkbox
  disableRipple
  edge="start"
  checked={sub.checked || false}
  onChange={() =>
    this.handleCheckClick(sub.id, parentIndex)
  }
/>

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

JavaScript - Receiving alert - AC_RunActiveContent.js needed for this page to function

When I attempt to open the HTML file in my application, a pop-up message appears stating that "This page requires AC_RunActiveContent.js." However, I have already imported and referenced the AC_RunActiveContent.js file in my package. Can someone assist m ...

Styling triangles within a CSS triangle

I'm attempting to design a webpage with a fixed triangle navigation element. The issue I am encountering is that I am unable to position smaller triangles inside the larger one, as shown in the image below. https://i.stack.imgur.com/1bTj8.png As th ...

Tips on creating a horizontal scrolling effect using the mouse

Is there a way to enable horizontal scrolling by holding down the mouse click, instead of relying on the horizontal scroll bar? And if possible, can the scroll bar be hidden? In essence, I am looking to replicate the functionality of the horizontal scroll ...

I am unable to correctly fetch the data string using Jquery Ajax from the server

I have implemented a jQuery Ajax function to check the availability of a username in real-time from the database. If the username is not available, the response is marked as "Unavailable" and vice versa. While I am successfully receiving this response, I a ...

The process of obtaining points through accurate responses using form inputs

My task is to create a unique quiz consisting of 10 questions. Half of the questions are multiple choice, which require radio inputs, while the other half are written answers that need text inputs. To ensure accuracy and provide a scoring system, I came ac ...

"TypeScript function returning a boolean value upon completion of a resolved promise

When working on a promise that returns a boolean in TypeScript, I encountered an error message that says: A 'get' accessor must return a value. The code snippet causing the issue is as follows: get tokenValid(): boolean { // Check if curre ...

Missing ng-required fields not displaying the has-error validation in AngularJS forms

While editing any part of their address, the user should see a red invalid border around each field to indicate that the full form is required. However, for some reason I can't seem to get the 'Address' field to display this border. The set ...

Using jQuery and regex to validate a long string containing lowercase letters, uppercase letters, numbers, special characters, and

Good day, I've been struggling with jquery regex and could really use some assistance. I've been stuck on this since last night and finally decided to seek help :) Here is my regex code along with the string stored in the 'exg' variabl ...

Updating is not happening with ng-repeat trackBy in the case of one-time binding

In an attempt to reduce the number of watchers in my AngularJS application, I am using both "track by" in ngRepeat and one-time bindings. For instance: Here is an example of my view: <div ng-repeat="item in items track by trackingId(item)"> {{ : ...

Trouble retrieving desired data from an array of objects in React Native

I'm having trouble retrieving values from an array of objects in my state. When I try to access the values, it only prints out "[Object Object]". However, when I stored the values in a separate array and used console.log, I was able to see them. Here ...

Issue when trying to use both the name and value attributes in an input field simultaneously

When the attribute "name" is omitted, the value specified in "value" displays correctly. However, when I include the required "name" attribute to work with [(ngModel)], the "value" attribute stops functioning. Without using the "name" attribute, an error ...

Utilizing form data to upload images and send them back to the front end within a React js application

I am working on a project using NestJS and React JS to create an image uploader. In React, I have the following setup: const props = { onChange({ file, fileList }: any) { const fd = new FormData(); fd.append('img& ...

Injection of Angular state resolve into controller fails to occur

I'm attempting to ensure that the value from ui-router's resolve is successfully passed to the controller portalsForUserCtrl. Take a look at the router code below: (function () { 'use strict'; var myApp = angular.module("myApp", ["co ...

Getting a Next.js error after performing a hard refresh on a page that contains a dynamic query

I have encountered an issue with my Next.js app when I attempt to hard reload it in production mode. The error message I receive is 404 - File or directory not found. Below is the code snippet I am using: import { useRouter } from "next/router"; import ...

Tips for executing a Python function from JavaScript, receiving input from an HTML text box

Currently, I am facing an issue with passing input from an HTML text box to a JavaScript variable. Once the input is stored in the JavaScript variable, it needs to be passed to a Python function for execution. Can someone provide assistance with this pro ...

Executing functions in real-time using React Native

I'm fairly new to Object-Oriented Programming (OOP) and my understanding of promises, asynchronous/synchronous function execution is quite basic. Any guidance or help from your end would be greatly appreciated! Let's take a look at an example fr ...

Receiving the [object HTMLInputElement] on the screen rather than a numerical value

I have an input box where a user can enter a number. When they click a button, I want that number to be displayed on the page. However, instead of seeing the number, I am getting the output as [object HTMLInputElement]. Below is my TypeScript code: let qu ...

Encountering difficulty inserting ajax response into a specific div element

What could be the issue? I've included the getElementById and I am receiving a response, as confirmed by Firebug. The response is correct, but for some reason it's not populating my div area. <script> $(document).ready(function () { $( ...

Choosing the state object name dynamically within a React JS component

I have a quick question about updating state in React. How can I change a specific object in a copy of the state that is selected using e.target.name and then set to e.target.value? For example, if I want to change newState.age when e.target.name = age i ...

Tips for incorporating HTML code within a select option value?

I am working with AngularJS to create a Visual Composer for a website. One feature I want to incorporate is the ability to add HTML code based on the selection made in a dropdown menu. However, I am struggling to figure out how to include the HTML within t ...