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.