React setState and update() addon - reactjs

I'm a beginer using ReactJS and today I had a situation that I don't know how to be explain.
I'm working on a project with a similar situation as described bellow:
var update = React.addons.update;
class HelloWidget extends React.Component{
constructor(props) {
super(props);
this.state = {
group1: 'show',
group2: 'A'
};
this.Update = this.Update.bind(this);
this.handleChange1 = this.handleChange1.bind(this);
}
Update(e, value = ''){
let field = e;
if(!value) field = e.target.name
//this solution work
/*this.setState({
[field]: value || e.target.value
});*/
//this solution doesn't work
let theState = Object.assign({}, this.state),
updatedState = update(theState,{[field]: {$set: value || e.target.value}})
console.log("UPDATE RESULTS");console.log(updatedState);
this.setState(updatedState);
}
handleChange1(e) {
const filters = this.state
if(filters.group1 === 'show' && filters.group2 === 'C' ){
this.Update('group2', 'A');
}
this.Update(e);
}
render() {
const filters = this.state;
console.log("RENDER");console.log(filters);
return (
<div className="widget">
<div>
Group 1<br />
<input type="radio" value="show" name="group1" defaultChecked={filters.group1 === 'show'} onChange={this.handleChange1} /> Show All Group 2
<input type="radio" value="hide" name="group1" defaultChecked={filters.group1 === 'hide'} onChange={this.handleChange1} /> Hide 3rd option
</div>
<br /><br />
<div>
Group 2<br />
<input type="radio" value="A" name="group2" checked={filters.group2 === 'A'} onChange={this.Update} /> A
<input type="radio" value="B" name="group2" checked={filters.group2 === 'B'} onChange={this.Update} /> B
{filters.group1 === 'show' && <label><input type="radio" value="C" name="group2" checked={filters.group2 === 'C'} onChange={this.Update} /> C</label>}
</div>
</div>
);
}
}
ReactDOM.render(<HelloWidget />, document.getElementById('container'));
.widget {
width: 402px;
margin:10px auto;
padding:10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.5.4/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.5.4/react-dom.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
Shortly, I have a function that update state from different children Components. According attached source code, changing options in first radio group should show or hide an option (last) on second radio group. If the hidden option is checked then default (first) option should been checked after hide.
Everything works fine when I use setState() directly, but because of state object complexity, I used update() addon and the result is not the same - default option on second radio group is not checked after last is hidden.
Where is my issue using update()?
Thanks

Seems that the issue is what is sent to update: for working solution - just one field, using update() - entire state object.
If I will change the working part to :
let theState = Object.assign({}, this.state),
updatedState = Object.assign({}, theState, {
[field]: value || e.target.value
})
;
this.setState(updatedState);
then I will receive the same issue.

Related

REACT: conditionally rendering a alert if field left blank

I have the following React form:
import React from 'react';
export default class ChatBar extends React.Component {
mySubmitHandler = event => {
event.preventDefault();
/* you can access the value as below */
const inputName = this.refInputName.value;
const inputEmail = this.refInputEmail.value;
const inputMessage = this.refInputMessage.value;
// const inputStamp = this.convertDate(new Date())
const message = {name: inputName, email: inputEmail, content: inputMessage, stamp: inputStamp}
this.props.addMessage(message)
this.refInputMessage.value = ""
}
render() {
return (
<div>
<h4>Leave a Comment</h4>
<form onSubmit={this.mySubmitHandler}>
<label>Your name
<input
type="text"
name="name"
ref={(node) => (this.refInputName = node)}
/>
</label>
<label>Your email
<input
type="text"
name="email"
ref={(node) => (this.refInputEmail = node)}
/>
</label>
<label>Your message
<textarea ref={(node) => (this.refInputMessage = node)} />
</label>
<br />
<input className="submit-button" type="submit" value="Submit comment" />
</form>
</div>
)
};
};
I need to create a way so that when an input is left black and either submitted or hovered over, it creates a "tool tip" alerting the user the field has been left blank (see attached image). I have tread fooling around with onHover, onClick and onSubmit handlers to render some state of tool tip being "true" and conditionally render the toolTip div however it does not seem to be working and I am rather lost, now starting from scratch again.
Any help is greatly appreciated =)
I recommend react-valida-hook, it's really simple to use, you can add personalized messages, the only thing you need to do is pass the error.
Example:
const displayError = (errs) => {
if (errs.indexOf('required') !== -1) {
return '*Super important required field';
}
if (errs.indexOf('minLength') !== -1) {
return '*Too short man!';
}
if (errs.indexOf('isEmail') !== -1) {
return '*That looks wrong';
}
return '';
};
<div className="errors">
// I use a variable to show only errors wen form is submitted
{submitted && displayError(validation.errors.firstName)}
</div>
You can make two custom CSS class for visibility: hidden, ect.
Then render the toolTip div like such:
<div className="tool-tip" style={this.state.showTip ? visible : hidden}>testing </div>

Possible to Interact with Custom Javascript Object Handler

I am trying to migrate the handling of my bootstrap date range picker from jQuery to ReactJS and while I am able to handle most interactions, I am struggling to figure out how I can migrate the following method to my reactjs setup>
This interaction takes the values selected from the calendar component on "Apply" and then sets two hidden input fields that I have that are sent to my server on form submission.
jQuery:
//Set annotationDateRange value on picker selection
$('input[name="annotationDateRange"]').on('apply.daterangepicker', function(ev, picker) {
$(this).val(picker.startDate.format('MM/DD/YYYY') + ' - ' + picker.endDate.format('MM/DD/YYYY'));
$("input[name='annotationStartDate']").val(picker.startDate.format('MM/DD/YYYY'));
$("input[name='annotationEndDate']").val(picker.endDate.format('MM/DD/YYYY'));
});
ReactJS (I thought add the handleChange() to the field would pick up on the calendar selection changes, but it appears they populate the text field in a way that the virtual DOM does not pick up on it):
import React from 'react';
import isEqual from 'lodash/isEqual';
export default class DateFilter extends React.Component {
constructor(props) {
super(props);
this.state = {
startDateValue: this.props.startDateQuery ? this.props.startDateQuery: '',
endDateValue:this.props.endDateQuery ? this.props.endDateQuery: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
console.log("New Handle Change")
/*console.log(input + " " + value)
this.setState({
[input]: value
})*/
}
componentDidMount() {
this.setState({
startDateValue: this.props.startDateQuery,
endDateValue: this.props.endDateQuery
});
}
componentWillReceiveProps(nextProps) {
if (this.props.startDateQuery != nextProps.startDateQuery && this.props.endDateQuery != nextProps.endDateQuery){
this.setState({ startDateValue: nextProps.startDateQuery, endDateValue: nextProps.endDateQuery });
}
}
render() {
return (
<div className="col-md-3">
<div className="input-group annotation-filter-date-range-picker">
<p>Annotation Date Range:</p>
</div>
<div className="input-group annotationFilterDatePicker">
<span className="input-group-addon"><i className="glyphicon glyphicon-calendar"></i></span>
<input type="text" name="annotationDateRange" className="form-control annotationFilterDatePicker" onChange={this.handleChange} autoComplete="off" />
</div>
<input type="hidden" name="annotationStartDate" className="form-control" value={this.state.startDateValue ? this.state.startDateValue : ""} onChange={this.handleChange} />
<input type="hidden" name="annotationEndDate" className="form-control" value={this.state.endDateValue ? this.state.endDateValue : ""} onChange={this.handleChange} />
</div>
);
}
}
Use arrow functions to not lose the Component scope.
handleChange = (event) => {
this.setState({
[input]: value
})
}
Or you can just call it as an arrow function
<input type="text" name="annotationDateRange" className="form-control annotationFilterDatePicker" onChange={(event) => this.handleChange(event)} autoComplete="off" />
In a NON ES6 way you can just bind 'this' to the function.
<input type="text" name="annotationDateRange" className="form-control annotationFilterDatePicker" onChange={this.handleChange.bind(this)} autoComplete="off" />

How to fetch input from text box and print in React?

I am new to React trying to write a very simple project that fetches input of both text boxes and when button is clicked, the 'data' in text boxes is printed on paragraph.
How do I fetch text's in input text boxes when button is clicked?
class Input extends Component {
state = {
tagged: false,
message: '',
}
handleClick(e) {
this.setState({tagged: true});
e.preventDefault();
console.log('The link was clicked.');
}
render() {
return (
<div id="id" style={divStyle}>
<p> hello </p>
<input
style = {textStyle}
placeholder="user#email.com"
type="text">
</input>
<input
style = {textStyle}
placeholder="tag"
type="text">
</input>
<button
onClick={(e) => this.handleClick(e)}
style={buttonStyle}>
{this.state.tagged ? 'Tagged' : 'Tag ' }
</button>
<p>
{this.state.tagged ? 'Clicked' : 'Still' }
</p>
</div>
)
}
}
You can add onChange event handler in each input.
class Input extends Component {
state = {
tagged: false,
message: '',
input1: '',
input2: '',
}
handleClick(e) {
// access input values in the state
console.log(this.state) // {tagged: true, input1: 'text', input2: 'text2'}
this.setState({tagged: true});
e.preventDefault();
console.log('The link was clicked.');
}
handleInputChange = (e, name) => {
this.setState({
[name]: e.target.value
})
}
render() {
return (
<div id="id" style={divStyle}>
<p> hello </p>
<input
style = {textStyle}
placeholder="user#email.com"
type="text"
onChange={(e) => this.handleInputChange(e, 'input1')}
>
</input>
<input
style = {textStyle}
placeholder="tag"
type="text"
onChange={(e) => this.handleInputChange(e, 'input2')}
>
</input>
<button
onClick={(e) => this.handleClick(e)}
style={buttonStyle}>
{this.state.tagged ? 'Tagged' : 'Tag ' }
</button>
<p>
{this.state.tagged ? 'Clicked' : 'Still' }
</p>
</div>
)
}
}
There are two different ways of working with react inputs - you can either make them controlled or uncontrolled. When you say fetch text from inputs, this is called uncontrolled components and means that form data is handled by the DOM itself and not by react.
This is achieved by using ref and literally getting a reference to your input and fetching its value when you need it. you can read more about this approach in react docs.
According to react docs, it is recommended using controlled components
In most cases, we recommend using controlled
components to implement forms. In a controlled
component, form data is handled by a React component.
This means that you don’t use references to the inputs and instead handle changes of your inputs with an event handler and update state with the new values that the user has entered into the input fields. According to react docs here is how react handles form with controlled components:
the React component that
renders a form also controls what happens in that form on subsequent
user input. An input form element whose value is controlled by React in this way is called a “controlled component”.
In your case you can do this if you choose controlled inputs:
class ControlledInput extends React.Component {
constructor(props) {
super(props);
this.state = {
tagged: false,
firstInput: '',
secondInput: ''
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
handleClick(e) {
this.setState({ tagged: true });
e.preventDefault();
console.log('The link was clicked.');
}
render() {
const { firstInput, secondInput, tagged } = this.state;
return (
<div id="id">
{tagged && <p>{firstInput} {secondInput}</p> }
<input
value={firstInput}
name="firstInput"
onChange={this.handleChange}
type="text" />
<input
value={secondInput}
name="secondInput"
onChange={this.handleChange}
type="text" />
<button onClick={(e) => this.handleClick(e)}>
{tagged ? 'Tagged' : 'Tag '}
</button>
</div>
)
}
}
Here you put the inputs' values on state and update state when the user writes something in your inputs. If you however want to use uncontrolled components you can do it this way:
class UncontrolledInput extends React.Component {
state = {
tagged: false,
message: '',
}
handleClick(e) {
e.preventDefault();
const messageFromInputs = `${this.firstInput.value} ${this.secondInput.value}`;
this.setState({ tagged: true, message: messageFromInputs });
}
render() {
return (
<div id="id">
<p>{this.state.message}</p>
<input ref={(input) => this.firstInput = input} type="text" />
<input ref={(input) => this.secondInput = input} type="text" />
<button onClick={(e) => this.handleClick(e)}>
{this.state.tagged ? 'Tagged' : 'Tag '}
</button>
<p>
{this.state.tagged ? 'Clicked' : 'Still'}
</p>
</div>
)
}
}
Here you will actually fetch values from your inputs when the button is clicked.
I made a working example with both ways on codesandbox.

How to set default Checked in checkbox ReactJS?

I'm having trouble to update the checkbox state after it's assigned with default value checked="checked" in React.
var rCheck = React.createElement('input',
{
type: 'checkbox',
checked: 'checked',
value: true
}, 'Check here');
After assigning checked="checked", I cannot interact the checkbox state by clicking to uncheck/check.
To interact with the box you need to update the state for the checkbox once you change it. And to have a default setting you can use defaultChecked.
An example:
<input type="checkbox" defaultChecked={this.state.chkbox} onChange={this.handleChangeChk} />
There are a few ways to accomplish this, here's a few:
Written using State Hooks:
function Checkbox() {
const [checked, setChecked] = React.useState(true);
return (
<label>
<input type="checkbox"
defaultChecked={checked}
onChange={() => setChecked(!checked)}
/>
Check Me!
</label>
);
}
ReactDOM.render(
<Checkbox />,
document.getElementById('checkbox'),
);
Here is a live demo on JSBin.
Written using Components:
class Checkbox extends React.Component {
constructor(props) {
super(props);
this.state = {
isChecked: true,
};
}
toggleChange = () => {
this.setState({
isChecked: !this.state.isChecked,
});
}
render() {
return (
<label>
<input type="checkbox"
defaultChecked={this.state.isChecked}
onChange={this.toggleChange}
/>
Check Me!
</label>
);
}
}
ReactDOM.render(
<Checkbox />,
document.getElementById('checkbox'),
);
Here is a live demo on JSBin.
If the checkbox is created only with React.createElement then the property
defaultChecked is used.
React.createElement('input',{type: 'checkbox', defaultChecked: false});
Credit to #nash_ag
In the React rendering lifecycle, the value attribute on form elements
will override the value in the DOM. With an uncontrolled component,
you often want React to specify the initial value, but leave
subsequent updates uncontrolled. To handle this case, you can specify
a defaultValue or defaultChecked attribute instead of value.
<input
type="checkbox"
defaultChecked={true}
/>
Or
React.createElement('input',{type: 'checkbox', defaultChecked: true});
Please checkout more details regarding defaultChecked for checkbox below:
https://reactjs.org/docs/uncontrolled-components.html#default-values
in addition to the correct answer you can just do :P
<input name="remember" type="checkbox" defaultChecked/>
import React, { useState } from 'react'
const [rememberUser, setRememberUser] = useState(true) //use false for unchecked initially
<input
type="checkbox"
checked={rememberUser}
onChange={() => {
setRememberUser(!rememberUser)
}}
/>
Value would be whether true or false defaultChecked={true}
<input type="checkbox"
defaultChecked={true}
onChange={() => setChecked(!checked)}
/>
It`s working
<input type="checkbox" value={props.key} defaultChecked={props.checked} ref={props.key} onChange={this.checkboxHandler} />
And function init it
{this.viewCheckbox({ key: 'yourKey', text: 'yourText', checked: this.state.yourKey })}
You may pass "true" or "" to the checked property of input checkbox. The empty quotes ("") will be understood as false and the item will be unchecked.
let checked = variable === value ? "true" : "";
<input
className="form-check-input"
type="checkbox"
value={variable}
id={variable}
name={variable}
checked={checked}
/>
<label className="form-check-label">{variable}</label>
I tried to accomplish this using Class component:
you can view the message for the same
.....
class Checkbox extends React.Component{
constructor(props){
super(props)
this.state={
checked:true
}
this.handleCheck=this.handleCheck.bind(this)
}
handleCheck(){
this.setState({
checked:!this.state.checked
})
}
render(){
var msg=" "
if(this.state.checked){
msg="checked!"
}else{
msg="not checked!"
}
return(
<div>
<input type="checkbox"
onChange={this.handleCheck}
defaultChecked={this.state.checked}
/>
<p>this box is {msg}</p>
</div>
)
}
}
Here's a code I did some time ago, it might be useful.
you have to play with this line => this.state = { checked: false, checked2: true};
class Componente extends React.Component {
constructor(props) {
super(props);
this.state = { checked: false, checked2: true};
this.handleChange = this.handleChange.bind(this);
this.handleChange2 = this.handleChange2.bind(this);
}
handleChange() {
this.setState({
checked: !this.state.checked
})
}
handleChange2() {
this.setState({
checked2: !this.state.checked2
})
}
render() {
const togglecheck1 = this.state.checked ? 'hidden-check1' : '';
const togglecheck2 = this.state.checked2 ? 'hidden-check2' : '';
return <div>
<div>
<label>Check 1</label>
<input type="checkbox" id="chk1"className="chk11" checked={ this.state.checked } onChange={ this.handleChange } />
<label>Check 2</label>
<input type="checkbox" id="chk2" className="chk22" checked={ this.state.checked2 } onChange={ this.handleChange2 } />
</div>
<div className={ togglecheck1 }>show hide div with check 1</div>
<div className={ togglecheck2 }>show hide div with check 2</div>
</div>;
}
}
ReactDOM.render(
<Componente />,
document.getElementById('container')
);
CSS
.hidden-check1 {
display: none;
}
.hidden-check2 {
visibility: hidden;
}
HTML
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
here's the codepen => http://codepen.io/parlop/pen/EKmaWM
In my case I felt that "defaultChecked" was not working properly with states/conditions. So I used "checked" with "onChange" for toggling the state.
Eg.
checked={this.state.enabled} onChange={this.setState({enabled : !this.state.enabled})}
If someone wants to handle dynamic data with multiple rows, this is for handing dynamic data.
You can check if the rowId is equal to 0.
If it is equal to 0, then you can set the state of the boolean value as true.
interface MyCellRendererState {
value: boolean;
}
constructor(props) {
super(props);
this.state = {
value: props.value ? props.value : false
};
this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
}
handleCheckboxChange() {
this.setState({ value: !this.state.value });
};
render() {
const { value } = this.state;
const rowId = this.props.rowIndex
if (rowId === 0) {
this.state = {
value : true }
}
return (
<div onChange={this.handleCheckboxChange}>
<input
type="radio"
checked={this.state.value}
name="print"
/>
</div>
)
}
Don't make it too hard. First, understand a simple example given below. It will be clear to you. In this case, just after pressing the checkbox, we will grab the value from the state(initially it's false), change it to other value(initially it's true) & set the state accordingly. If the checkbox is pressed for the second time, it will do the same process again. Grabbing the value (now it's true), change it(to false) & then set the state accordingly(now it's false again. The code is shared below.
Part 1
state = {
verified: false
} // The verified state is now false
Part 2
verifiedChange = e => {
// e.preventDefault(); It's not needed
const { verified } = e.target;
this.setState({
verified: !this.state.verified // It will make the default state value(false) at Part 1 to true
});
};
Part 3
<form>
<input
type="checkbox"
name="verified"
id="verified"
onChange={this.verifiedChange} // Triggers the function in the Part 2
value={this.state.verified}
/>
<label for="verified">
<small>Verified</small>
</label>
</form>
<div className="display__lbl_input">
<input
type="checkbox"
onChange={this.handleChangeFilGasoil}
value="Filter Gasoil"
name="Filter Gasoil"
id=""
/>
<label htmlFor="">Filter Gasoil</label>
</div>
handleChangeFilGasoil = (e) => {
if(e.target.checked){
this.setState({
checkedBoxFG:e.target.value
})
console.log(this.state.checkedBoxFG)
}
else{
this.setState({
checkedBoxFG : ''
})
console.log(this.state.checkedBoxFG)
}
};
You can use a state var "enableSwitch" and a function "handleSwitch" to handle your default checked Switch:
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="switchId" checked={this.state.enableSwitch} onClick={this.handleSwitch}/>
<label class="custom-control-label" for="switchId">switch text</label>
</div>
Here's the function which inverts the variable if the user clicks on the switch:
handleSwitch = (e) => {
this.setState({ enableSwitch: !this.state.enableSwitch });
}
I know it's a late reply to an old question, but this short solution may help other users.
<div className="form-group">
<div className="checkbox">
<label><input type="checkbox" value="" onChange={this.handleInputChange.bind(this)} />Flagged</label>
<br />
<label><input type="checkbox" value="" />Un Flagged</label>
</div>
</div
handleInputChange(event){
console.log("event",event.target.checked) }
the Above handle give you the value of true or false upon checked or unChecked
I set the state as any[] type. and in the constructor set the state to null.
onServiceChange = (e) => {
const {value} = e.target;
const index = this.state.services.indexOf(value);
const services = this.state.services.filter(item => item !== value);
this.setState(prevState => ({
services: index === -1 ? prevState.services.push(value) && prevState.services : this.state.services.filter(item => item !== value)
}))
}
In the input element
this.onServiceChange(e)}/>
this.onServiceChange(e)}/>
this.onServiceChange(e)}/>
this.onServiceChange(e)}/>
I figured it out after some time. Thought it might help y'all :)

React Checkbox not sending onChange

TLDR: Use defaultChecked instead of checked, working jsbin.
Trying to setup a simple checkbox that will cross out its label text when it is checked. For some reason handleChange is not getting fired when I use the component. Can anyone explain what I'm doing wrong?
var CrossoutCheckbox = React.createClass({
getInitialState: function () {
return {
complete: (!!this.props.complete) || false
};
},
handleChange: function(){
console.log('handleChange', this.refs.complete.checked); // Never gets logged
this.setState({
complete: this.refs.complete.checked
});
},
render: function(){
var labelStyle={
'text-decoration': this.state.complete?'line-through':''
};
return (
<span>
<label style={labelStyle}>
<input
type="checkbox"
checked={this.state.complete}
ref="complete"
onChange={this.handleChange}
/>
{this.props.text}
</label>
</span>
);
}
});
Usage:
React.renderComponent(CrossoutCheckbox({text: "Text Text", complete: false}), mountNode);
Solution:
Using checked doesn't let the underlying value change (apparently) and thus doesn't call the onChange handler. Switching to defaultChecked seems to fix this:
var CrossoutCheckbox = React.createClass({
getInitialState: function () {
return {
complete: (!!this.props.complete) || false
};
},
handleChange: function(){
this.setState({
complete: !this.state.complete
});
},
render: function(){
var labelStyle={
'text-decoration': this.state.complete?'line-through':''
};
return (
<span>
<label style={labelStyle}>
<input
type="checkbox"
defaultChecked={this.state.complete}
ref="complete"
onChange={this.handleChange}
/>
{this.props.text}
</label>
</span>
);
}
});
To get the checked state of your checkbox the path would be:
this.refs.complete.state.checked
The alternative is to get it from the event passed into the handleChange method:
event.target.checked
It's better not to use refs in such cases. Use:
<input
type="checkbox"
checked={this.state.active}
onClick={this.handleClick}
/>
There are some options:
checked vs defaultChecked
The former would respond to both state changes and clicks.
The latter would ignore state changes.
onClick vs onChange
The former would always trigger on clicks.
The latter would not trigger on clicks if checked attribute is present on input element.
If you have a handleChange function that looks like this:
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
});
}
You can create a custom onChange function so that it acts like an text input would:
<input
type="checkbox"
name="check"
checked={this.state.check}
onChange={(e) => {
this.handleChange({
target: {
name: e.target.name,
value: e.target.checked,
},
});
}}
/>
In the scenario you would NOT like to use the onChange handler on the input DOM, you can use the onClick property as an alternative. The defaultChecked, the condition may leave a fixed state for v16 IINM.
class CrossOutCheckbox extends Component {
constructor(init){
super(init);
this.handleChange = this.handleChange.bind(this);
}
handleChange({target}){
if (target.checked){
target.removeAttribute('checked');
target.parentNode.style.textDecoration = "";
} else {
target.setAttribute('checked', true);
target.parentNode.style.textDecoration = "line-through";
}
}
render(){
return (
<span>
<label style={{textDecoration: this.props.complete?"line-through":""}}>
<input type="checkbox"
onClick={this.handleChange}
defaultChecked={this.props.complete}
/>
</label>
{this.props.text}
</span>
)
}
}
I hope this helps someone in the future.
In case someone is looking for a universal event handler the following code can be used more or less (assuming that name property is set for every input):
this.handleInputChange = (e) => {
item[e.target.name] = e.target.type === "checkbox" ? e.target.checked : e.target.value;
}
onChange will not call handleChange on mobile when using defaultChecked. As an alternative you can can use onClick and onTouchEnd.
<input onClick={this.handleChange} onTouchEnd={this.handleChange} type="checkbox" defaultChecked={!!this.state.complete} />;
In material ui, state of checkbox can be fetched as
this.refs.complete.state.switched

Resources