5

I use Material UI checkbox component, and try toggle state onCheck, in console state changes but in UI not, the check mark does not toggle. what did I mess.

class CheckboxInteractivity extends React.Component {

    state = {
        switched: false,
    }

    componentWillMount() {
        const {checked} = this.props
        if (checked) {
            this.setState({
                switched: true,
            })
        }
    }

    handleChange = (event, switched) => {
        this.setState({switched: !this.state.switched})
    }

    render () {
        const {switched} = this.state

        return <Checkbox
            label="Label"
            checked={switched}
            onCheck={this.handleChange}
            {...this.props}
                />
    }
}

CheckboxInteractivity.propTypes = {
    checked: PropTypes.bool,
}

export default CheckboxInteractivity

components

<CheckboxInteractivity /> 
//working correctly
<CheckboxInteractivity checked/>
//not working 

2 Answers 2

6

Reason why it is not working with second case is:

return <Checkbox
            label="Label"
            checked={switched}
            onCheck={this.handleChange}
            {...this.props}
       />

Will become:

return <Checkbox
            label="Label"
            checked={switched}
            onCheck={this.handleChange}

            checked={true}                     //here

       />

You are using two checked property and second will make the checkbox checked true always irrespective of the state variable that's why. Remove {...this.props} it will work as expected.

Why it is working in first case is, you are not passing the checked so checkbox will find only one checked key and it will render the component on the basis of that.

Here {...this.props} is not required because you are already storing the value in state.

Suggestion:

Instead of setting the props value in state in componentWillMount lifecycle method set that in constructor only, like this:

constructor(props){
    super(props);
    this.state = {
        switched: props.checked || false,
    }
}

Update:

Let's say, you are passing many values in props and few values you want to override in component, so what you need to do here is, first apply all the props properties, then define the other properties. By this way, component properties will override the props properties.

Like this:

return <Checkbox
            {...this.props}                //first apply props values then other
            label="Label"
            checked={switched}
            onCheck={this.handleChange}                
       />
Sign up to request clarification or add additional context in comments.

2 Comments

Only one issue in case if I want to try to add props disable I need {...this.props}, because depends on this props I set styles <CheckboxInteractivity checked/>
@PalaniichukDmytro check the updated answer, update section. You just need to apply the props values first then the other values, ordering will solve your issue :)
0

I ran into this problem when using two Mui Checkboxes which values depends on each other.

I had "parent state" which I tried to use within both of the checkboxes. I provided this state using context provider.

Solution

I solved the problem by initializing separate state const [checked, setChecked] = useState(false) inside both of the checkbox components. I did this to prevent "uncontrolled" component initialization.

To bind "checked" states to parent state, I defined a simple useEffect() function.

Like this:

export const DrugUsageStartCheckBox = () => {
    const { t } = useTranslation();
    // parent state can be used only if component is wrapped to context provider.
    const {state, dispatch} = useParentState();
    const [checked, setChecked] = useState(false)

    useEffect(() => {
        setChecked(state.checked)
    }, [state.checked])

    return (
            <Checkbox
                id={'my-checkbox'}
                checked={checked}
                onChange={(e) => {
                    dispatch({type: "toggleChecked"})
                }}
    ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.