3

I am using material-ui

Here my react component goes:

import Checkbox from '@material-ui/core/Checkbox'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import React from "react"; import { withStyles } from "@material-ui/core/styles"; const styles = (theme) => ({ }); class SomeComponent extends React.Component { static propTypes = { }; state = { checked: true, } handleChange = name => event => { event.persist() this.setState({ [name]: event.target.checked }, () => { if (event.target.checked) { this.props.parentMethod1(event.target.value) } else { this.props.parentMethod2(event.target.value) } }); }; render() { const { user } = this.props; return ( <div> <FormControlLabel control={ <Checkbox checked={this.state.checked} onChange={this.handleChange('checked')} value={user.id} color="primary" /> } label={user.first_name} /> </div> ); } } export default withStyles(styles)(SomeComponent); 

The problem is, I can select/unselect the checkBox only once. After selecting/deselecting the checkbox, onChange event is not occuring.

Can you help me how to make Checkbox work as the way it is? Thanks.

Here is the reproduced error:

https://codesandbox.io/s/y041zknrqv

5
  • 1
    Instead of using event.target.checked and event.target.value in the callback, you can put checked and value in variables the first thing you do in the function returned from handleChange: const { checked, value } = event.target and use that instead. This way you don't need to persists the event. Does that fix the issue? Commented Nov 15, 2018 at 15:52
  • This will remove the warning but issue is not fixed yet. Commented Nov 15, 2018 at 16:00
  • Hi there. I can't seem to reproduce the problem using similar code to yours: codesandbox.io/s/m788313rvp Commented Nov 15, 2018 at 17:01
  • Using just this much, we can't reproduce the error. The parent component has few synthetic events and it's too huge to add here. I will try to minimize the code and edit here. Commented Nov 15, 2018 at 17:18
  • @AndyJ Please see the codesandbox.io/s/y041zknrqv Commented Nov 15, 2018 at 18:49

3 Answers 3

5

Original codesandbox by OP: https://codesandbox.io/s/y041zknrqv

If the above codesandbox correctly demonstrates your actual problem, then your issue is that you mess up with event.stopPropagation and event.preventDefault

In both Parent1 and Parent2, you provide onClick event handler to the div container and implement event.preventDefault and event.stopPropagation on both handlers. So here is what happens when you click the checkbox the first time:

  • Checkbox receives click event and updates state, resulting in checked = true.
  • Event bubbles up to Parent2. Here onClick triggers function handleClick of this component.
  • in handleClick, event.preventDefault stops default action of browser for that event, meaning future click events will not trigger checkbox, while event.stopPropagation prevents parent components from firing onClick, meaning Parent1 will immediately never receive any click event.

And now, from the second click event onwards, only Parent2 can receive and response. Its children and its parents will not handle anything anymore. You can see the console log in here: https://codesandbox.io/s/r75rp285xq

So, to fix your issue, remove event.preventDefault from Parent2's handleClick. If you also want to correct behavior of Parent1, remove event.preventDefault from both components and remove event.stopPropagation from Parent2

Sign up to request clarification or add additional context in comments.

Comments

1

If you meant to change the value of checkbox. You must not pass same value onChange in your case

onChange={(e)=>this.handleChange(e)} 

and your handle change function should be like

handleChange =event=> { this.setState(prevState=>{ checked: !prevState.checked }, () => { if (this.state.checked) { this.props.parentMethod1(this.state.checked) } else { this.props.parentMethod2(this.state.checked) } }); }; 

This will change your value every onChange event.

2 Comments

I need values to my parent methods. Can you please go through this : codesandbox.io/s/y041zknrqv ? It might clear the question.
It is working fine when I just use in that component itself. Your parent components are not updating because you are not pass the value to the parent component. please refer the link codesandbox.io/s/00qpz5vnxl
-1

Since you are passing the function a parameter, try converting it into an arrow function on your onChange event

<Checkbox checked={this.state.checked} onChange={() => this.handleChange('checked')} value={user.id} color="primary" /> 

2 Comments

No, not helping. Thanks
this.handleChange('checked') creates a handler function, handleChange = name => event => { rather than being the handler function itself. So while this is a good suggestion in general, it doesn't apply to this code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.