Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - onChange function 'this.state' is undefined

I'm experimenting with React and I'm trying to create a Search to filter a list of items. I have two components, the main one displaying the list of items which calls the Search component.

I have an onChange function that sets the term in the state as the input value and then calls searchItems from the main component to filter the list of items. For some reason in searchItems, this.state is undefined. I thought adding bind to onInputChange in the Search component would sort it out but it did not make any difference. Maybe there's something I'm missing.

Main Component

import React, { Component } from 'react';
import _ from 'lodash';

import Search from './search';

class Items extends Component {
    constructor(props) {
        super(props);
        this.state = {
            error: null,
            isLoaded: false,
            items: []
        };
    }

    componentDidMount() {
        fetch("[url].json")
            .then(res => res.json())
            .then(
                (result) => {
                    this.setState({
                        isLoaded: true,
                        items: result
                    });
                }
            ),
            (error) => {
                this.setState({
                    isLoaded: true,
                    error
                })
            }
    }

    searchItems(term) {
        const { items } = this.state;
        const filtered = _.filter(items, function(item) {
            return item.Name.indexOf(term) > -1;
        });

        this.setState({ items: filtered });
    }

    render() {
        const { error, isLoaded, items } = this.state;

        if (error) {
            return <div>Error: {error.message}</div>;
        }
        else if (!isLoaded) {
            return <div>Loading...</div>;
        }
        else {
            return (
                <div>
                    <Search onSearch={this.searchItems}/>
                    <ul>
                        {items.map(item => (
                            <li key={item.GameId}>
                                {item.Name}
                            </li>
                        ))}
                    </ul>
                </div>
            )
        }
    }
}

export default Items;

Search Component

import React, { Component } from 'react';

class Search extends Component {
    constructor(props) {
        super(props);

        this.state = {
            term: ''
        };
    }

    render() {
        return (
            <div>
                <input type="text" placeholder="Search" value={this.state.term} onChange={event => this.onInputChange(event.target.value)} />
            </div>
        );
    }

    onInputChange(term) {
        this.setState({ term });
        this.props.onSearch(term);
    }
}

export default Search;
like image 525
j.grima Avatar asked Dec 03 '22 20:12

j.grima


1 Answers

You didn't bind searchItems() in the Items component.

Try changing it to an arrow function:

searchItems = () => {
  // blah
}

or otherwise binding it in the constructor():

constructor() {
  // blah
  this.searchItems = this.searchItems.bind(this);
}

or when you call it.

You can read more about this here.

like image 74
Colin Ricardo Avatar answered Dec 08 '22 01:12

Colin Ricardo