1

I have the following problem - I can't read value from my state, I get the error:

Cannot read property 'state' of undefined

My class component with a state:

class SideNav extends Component {

    state = {
        brand: 'Thule'
    }

    handleToggle = () => this.setState({open: !this.state.open});



    handleBrand = (evt) => {
        this.setState({brand: evt.target.value});
        console.log(this.state.brand); --> WORKS HERE!!!
    }

    searchProducts() {
        console.log(this.state.brand); --> ERROR: cannot read 'state' property of undefined
    }

    render() {
        return (
            <div className={classes.sideNav}>
                <Button variant={"outlined"} onClick={this.handleToggle} className={classes.sideNavBtn}>Search</Button>
                <Drawer
                    className={classes.drawer}
                    containerStyle={{top: 55}}
                    docked={false}
                    width={200}
                    open={this.state.open}
                    onRequestChange={open => this.setState({open})}
                >
                    <AppBar title="Search"/>
                    <form noValidate autoComplete="off" onSubmit={this.searchProducts}>
                        <TextField
                            id="brand"
                            label="Brand"
                            margin="normal"
                            onChange={this.handleBrand}
                        />
                        <Button variant="contained" color="primary" onClick={this.searchProducts}>
                            Search
                        </Button>
                    </form>
                </Drawer>
            </div>
        );
    }
}

export default SideNav;

I wonder WHY I'm able to read my this.state.bran value in:

handleBrand = (evt) => {
        this.setState({brand: evt.target.value});
        console.log(this.state.brand);
    }

but NOT in

 searchProducts() {
        console.log(this.state.brand);
    }

I don't understand this case.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Matley
  • 1,953
  • 4
  • 35
  • 73
  • Possible duplicate of [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Emile Bergeron Sep 17 '19 at 17:29

2 Answers2

4

searchProducts is a class method either bind it in constructor or use arrow functions (like in handleBrand). Currently your accessing the wrong value for this

searchProducts = () =>{}

Using bind

constructor(){
    this.searchProducts = this.searchProducts.bind(this)
}

Arrow functions have lexical this. By using this inside a class method you are accessing the local scope of searchProducts not the Component's instance

Dupocas
  • 20,285
  • 6
  • 38
  • 56
2

this works in confusing ways in JavaScript. It's not working as intended in searchProduct() because you're passing it as a prop to a child component. In your constructor you should bind it to the instance like this:

constructor(props) {
  super(props);
  this.searchProducts = this.searchProducts.bind(this);
}
joshwilsonvu
  • 2,569
  • 9
  • 20