简体   繁体   中英

Why won't my search bar and its functionality be displayed/work?

I'm making a search bar that allows the user to filter the name of the place that they're looking for as they're typing it making it easier (by narrowing down the selection) for them in order to choose their desired choice.

But for some reason, I'm getting the error in the browser below.

What am I doing wrong in my code & how can I fix it?

import React, { Component } from 'react';

let places = [
    {
        name: "something",
        location: "somewhere"
    },

    {
        name: "something2",
        location: "somewhere3"
    },

    {
        name: "something3",
        location: "somewhere4"
    },
];

class Search extends Component {
    constructor(props) {
        super(props);
        this.state = {
            searchString: "",
            places: []
        };

        this.handleChange = this.handleChange.bind(this);
    };

    componentDidMount() {
        this.setState({
            places: places
        });
        this.ref.search.focus();
    }

    handleChange() {
        this.setState({
           searchString: this.refs.search.value
        });
    }

    render() {
        let _places = this.state.places;
        let search = this.state.searchString.trim().toLowerCase();

        if(search.length > 0) {
            _places = _places.filter(function(places) {
                return places.name.toLowerCase().match(search);
            });
        }

        return(
            <div>
                <input
                    type="text"
                    value={this.state.searchString}
                    ref="search"
                    onChange={this.handleChange}
                />

                {
                    places.map(l => {
                        return(
                            <li>
                                {l.name} {l.location}
                            </li>
                        );
                    })
                }
            </div>
        );
    }
}

export default Search;

Error on the browser:

TypeError: Cannot read property 'search' of undefined

  38 |     this.setState({
  39 |         places: places
  40 |     });
> 41 |     this.ref.search.focus();
  42 | }
  43 | 
  44 | handleChange() { 

When using string refs, the ref is available inside an object named refs and not ref and hence you should access it like this.refs.search.focus();

However having said that, you must make use of either React.createRef if you are on version 16.3.0 or react or above or else use callback refs

Using createRef

class Search extends Component {
    constructor(props) {
        super(props);
        this.state = {
            searchString: "",
            places: []
        };
        this.search = React.createRef();
        this.handleChange = this.handleChange.bind(this);
    };

    componentDidMount() {
        this.setState({
            places: places
        });
        this.search.current.focus();
    }

    handleChange() {
        this.setState({
           searchString: this.search.current.value
        });
    }

    render() {
        let _places = this.state.places;
        let search = this.state.searchString.trim().toLowerCase();

        if(search.length > 0) {
            _places = _places.filter(function(places) {
                return places.name.toLowerCase().match(search);
            });
        }

        return(
            <div>
                <input
                    type="text"
                    value={this.state.searchString}
                    ref={this.search}
                    onChange={this.handleChange}
                />

                {
                    places.map(l => {
                        return(
                            <li>
                                {l.name} {l.location}
                            </li>
                        );
                    })
                }
            </div>
        );
    }
}

Using callback refs

class Search extends Component {
    constructor(props) {
        super(props);
        this.state = {
            searchString: "",
            places: []
        };

        this.handleChange = this.handleChange.bind(this);
    };

    componentDidMount() {
        this.setState({
            places: places
        });
        this.search.focus();
    }

    handleChange() {
        this.setState({
           searchString: this.search.value
        });
    }

    render() {
        let _places = this.state.places;
        let search = this.state.searchString.trim().toLowerCase();

        if(search.length > 0) {
            _places = _places.filter(function(places) {
                return places.name.toLowerCase().match(search);
            });
        }

        return(
            <div>
                <input
                    type="text"
                    value={this.state.searchString}
                    ref={(ref) => this.search = ref}
                    onChange={this.handleChange}
                />

                {
                    places.map(l => {
                        return(
                            <li>
                                {l.name} {l.location}
                            </li>
                        );
                    })
                }
            </div>
        );
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM