最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React - onChange function 'this.state' is undefined - Stack Overflow

programmeradmin3浏览0评论

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

I have an onChange function that sets the term in the state as the input value and then calls searchItems from the main ponent to filter the list of items. For some reason in searchItems, this.state is undefined. I thought adding bind to onInputChange in the Search ponent 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: []
        };
    }

    ponentDidMount() {
        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;

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

I have an onChange function that sets the term in the state as the input value and then calls searchItems from the main ponent to filter the list of items. For some reason in searchItems, this.state is undefined. I thought adding bind to onInputChange in the Search ponent 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: []
        };
    }

    ponentDidMount() {
        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;
Share Improve this question asked Apr 19, 2018 at 22:16 j.grimaj.grima 1,9413 gold badges24 silver badges46 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 18

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

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.

发布评论

评论列表(0)

  1. 暂无评论