galio-org / galio

Galio is a beautifully designed, Free and Open Source React Native Framework
https://galio.io/
MIT License
3.14k stars 325 forks source link

When onChange function passed to Checkbox it stops working #228

Open MileanCo opened 4 years ago

MileanCo commented 4 years ago

Describe the bug When you pass the onChange function the checkbox stops changing state and stays either checked or unchecked.

If you remove onChange(), then it works but I cannot do anything based on if it was clicked or not. I think this.setState() is what is messing it up.

        <Checkbox
            label="Apples"
            flexDirection="row"
            initialValue={true}
            onChange={(val) => {
              if (val) {
                  this.setState({apples: false});
                } else {
                  this.setState({apples: true});
                }
            }}
          />
phillx commented 4 years ago

@MileanCo I would say it's hard to guess what's wrong with your implementation, next time provide more info :)

But my hunch is that your code looks like this:

import React from "react";
import { Block,Checkbox } from "galio-framework";

export default class App extends React.Component {
    state = { apples: false };

    handleOnChange(val) {
        if (val) {
            this.setState({ apples: false });
        } else {
            this.setState({ apples: true });
        }
    };

    render() {
        return (
            <Block safe>
                <Checkbox
                    label="Apples"
                    flexDirection="row"
                    initialValue={true}
                    onChange={this.handleOnChange}
                />
            </Block>
        );
    }
}

Which means after you tap the checkbox, you get an error:

undefined is not an object (evaluating 'this.setState')

This error means you forgot to bind components context to your function = the handling function doesn't have access to the component's setState method.

You have to either bind context in the constructor, or use an arrow function:

import React from "react";
import { Block,Checkbox } from "galio-framework";

export default class App extends React.Component<{}> {
    state = { apples: false };

    handleOnChange = (val) => {
        if (val) {
            this.setState({ apples: false });
        } else {
            this.setState({ apples: true });
        }
    }

    render() {
        return (
            <Block safe>
                <Checkbox
                    label="Apples"
                    flexDirection="row"
                    initialValue={true}
                    onChange={this.handleOnChange}
                />
            </Block>
        );
    }
}