【发布时间】:2020-10-04 15:26:55
【问题描述】:
我正在尝试在我的 React 项目中添加一个谷歌自动完成功能到我的位置输入,但我收到了这个错误:InvalidValueError: not an instance of HTMLInputElement. 我猜当事件触发时我得到了错误,但我不知道它来自哪里。
这是我的代码
搜索.js
import React, { useState, useContext } from "react";
import DisplaySearchBar from "../layout/DisplaySearchBar";
import RestContext from "../context/restaurant/restContext";
import AlertContext from "../context/alert/alertContext";
const Search = () => {
const restContext = useContext(RestContext);
const alertContext = useContext(AlertContext);
const [where, setWhere] = useState("");
const [what, setWhat] = useState("");
const [sortBy, setSortBy] = useState("best_match");
const [city, setCity] = useState("");
const sortByOptions = {
"Best Match": "best_match",
"Highest Rated": "rating",
"Most Reviewed": "review_count",
};
// give active class to option selected
const getSortByClass = (sortByOption) => {
if (sortBy === sortByOption) {
return "active";
} else {
return "";
}
};
// set the state of a sorting option
const handleSortByChange = (sortByOption) => {
setSortBy(sortByOption);
};
//handle input changes
const handleChange = (e) => {
if (e.target.name === "what") {
setWhat(e.target.value);
} else if (e.target.name === "where") {
setWhere(e.target.value);
}
};
const onSubmit = (e) => {
e.preventDefault();
if (where && what) {
restContext.getRestaurants({ where, what, sortBy });
setWhere("");
setWhat("");
setSortBy("best_match");
} else {
alertContext.setAlert("Please insert somethiing", "error");
}
};
// displays sort options
const renderSortByOptions = () => {
return Object.keys(sortByOptions).map((sortByOption) => {
let sortByOptionValue = sortByOptions[sortByOption];
return (
<li
className={getSortByClass(sortByOptionValue)}
key={sortByOptionValue}
onClick={() => handleSortByChange(sortByOptionValue)}
>
{sortByOption}
</li>
);
});
};
// google suggestion
const handleScriptLoad = () => {
const handlePlaceSelect = () => {
// Extract City From Address Object
const addressObject = autocomplete.getPlace();
const address = addressObject.address_components;
// Check if address is valid
if (address) {
// Set State
setCity(address[0].long_name);
}
};
const options = {
types: ["(cities)"],
}; // To disable any eslint 'google not defined' errors
// Initialize Google Autocomplete
/*global google*/ let autocomplete = new google.maps.places.Autocomplete(
document.getElementById("autocomplete"),
options
);
// address.
autocomplete.setFields(["address_components", "formatted_address"]);
// Fire Event when a suggested name is selected
autocomplete.addListener("place_changed", handlePlaceSelect);
};
return (
<DisplaySearchBar
onSubmit={onSubmit}
handleChange={handleChange}
renderSortByOptions={renderSortByOptions}
where={where}
what={what}
handleScriptLoad={handleScriptLoad}
/>
);
};
export default Search;
DisplaySearch.js
import React, { useContext } from "react";
import PropTypes from "prop-types";
import RestContext from "../context/restaurant/restContext";
//Import React Script Libraray to load Google object
import Script from "react-load-script";
const DisplaySearchBar = ({
renderSortByOptions,
onSubmit,
where,
handleChange,
what,
handleScriptLoad,
}) => {
const restContext = useContext(RestContext);
const { restaurants, clearSearch } = restContext;
const googleUrl = `https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLE_API_KEY}&libraries=places`;
return (
<div className="searchBar">
<h1>Where are you going to eat tonigth?</h1>
<div className="searchBar-sort-options">
<ul>{renderSortByOptions()}</ul>
</div>
<form onSubmit={onSubmit} className="searchBar-form">
<div className="searchBar-input">
<Script url={googleUrl} onLoad={handleScriptLoad} />
<input
type="text"
name="where"
placeholder="Where do you want to eat?"
value={where}
onChange={handleChange}
/>
<input
type="text"
name="what"
placeholder="What do you want to eat?"
onChange={handleChange}
value={what}
/>
</div>
<div className="searchBar-submit">
<input
className="myButton button"
type="submit"
name="submit"
value="Search"
></input>
{restaurants.length > 0 && (
<button className="clearButton button" onClick={clearSearch}>
Clear
</button>
)}
</div>
</form>
</div>
);
};
DisplaySearchBar.propTypes = {
renderSortByOptions: PropTypes.func.isRequired,
where: PropTypes.string.isRequired,
handleChange: PropTypes.func.isRequired,
what: PropTypes.string.isRequired,
handleScriptLoad: PropTypes.func.isRequired,
};
export default DisplaySearchBar;
感谢您的帮助
【问题讨论】:
标签: javascript reactjs autocomplete googleplacesautocomplete