React出现Too many re-renders错误及Google Maps集成问题求助
问题排查与解决方案
一、先解决无限重渲染错误
你的代码里App.js的路由传参犯了个低级错误:
<Route exact path="/" element={<Form getdata={getData()} />}></Route>
这里直接调用了getData(),每次App组件渲染都会执行这个函数,而getData里调用setData又会触发App重新渲染,直接形成无限循环,导致React抛出重渲染限制错误。
修复步骤:
- 把函数调用改成传递函数引用,不要加括号:
<Route exact path="/" element={<Form getData={getData} />} /> - 注意参数名大小写统一,Form组件里用的是
props.getData,所以App里传的时候要写getData,不是getdata。 - 另外Form组件里的按钮是submit类型,包裹在Link里,点击会触发form的默认提交行为,导致页面刷新,要阻止默认行为:
onClick={(event) => { event.preventDefault(); props.getData(inputData); }}
二、集成Google Maps实现地点展示
我用@react-google-maps/api这个库来简化集成步骤,比直接写原生Google Maps API更省心:
1. 先装依赖
打开终端跑这条命令:
npm install @react-google-maps/api
2. 写Dashboard组件代码
创建Dashboard.js,实现用户信息展示+地图标记功能:
import React, { useState, useEffect } from "react"; import { GoogleMap, LoadScript, Marker } from "@react-google-maps/api"; // 地图容器样式 const containerStyle = { width: '800px', height: '600px' }; const Dashboard = ({ data }) => { const [mapCenter, setMapCenter] = useState({ lat: 0, lng: 0 }); const [markerPosition, setMarkerPosition] = useState(null); // 用地理编码API把地址转成经纬度 useEffect(() => { if (data.location) { const geocoder = new window.google.maps.Geocoder(); geocoder.geocode({ address: data.location }, (results, status) => { if (status === "OK") { const location = results[0].geometry.location; setMapCenter({ lat: location.lat(), lng: location.lng() }); setMarkerPosition({ lat: location.lat(), lng: location.lng() }); } else { alert(`地址解析失败: ${status}`); } }); } }, [data.location]); return ( <div> <h2>用户信息</h2> <p>姓名: {data.firstname || '未填写'}</p> <p>位置: {data.location || '未填写'}</p> {data.location && ( <LoadScript googleMapsApiKey="你的Google Maps API密钥"> <GoogleMap mapContainerStyle={containerStyle} center={mapCenter} zoom={12} > {markerPosition && <Marker position={markerPosition} />} </GoogleMap> </LoadScript> )} </div> ); }; export default Dashboard;
3. 注意事项
- 去Google Cloud平台申请API密钥,要确保启用了Maps JavaScript API和地理编码API,不然地图加载不出来
- 如果用户输入的地址太模糊,地理编码会失败,你可以把alert换成更友好的提示
- 要是想提升体验,可以给Form里的location输入框加Google Places自动补全,用户输入的时候会提示地址选项
三、修正后的完整代码
Form组件(修正版)
import React, { useState } from "react"; import { Link } from "react-router-dom"; const Form = (props) => { const [inputData, setInputData] = useState({ firstname: "", location: "" }); const InputHandle = (event) => { setInputData({ ...inputData, [event.target.name]: event.target.value }); }; return ( <div> <form id="form"> <div className="inputs"> <label htmlFor="firstname"> 姓名</label> <input type="text" id="firstname" name="firstname" value={inputData.firstname} onChange={InputHandle} /> </div> <div className="inputs"> <label htmlFor="location">所在位置</label> <input type="text" id="location" name="location" value={inputData.location} onChange={InputHandle} /> <Link to="/dashboard"> <button type="submit" className="btn" onClick={(event) => { event.preventDefault(); props.getData(inputData); }} > 提交 </button> </Link> </div> </form> </div> ); }; export default Form;
(注:把label的for改成了React支持的htmlFor,给input加了value绑定,确保是受控组件)
App组件(修正版)
import Dashboard from "./components/Dashboard"; import Form from "./components/Form"; import "./App.css"; import { BrowserRouter as Router, Routes, Route, } from "react-router-dom"; import { useState } from "react"; function App() { const [data, setData] = useState({}); const getData = (inputData) => { setData(inputData); }; return ( <Router> <div className="App"> <Routes> <Route exact path="/" element={<Form getData={getData} />} /> <Route exact path="/dashboard" element={<Dashboard data={data} />} /> </Routes> </div> </Router> ); } export default App;
内容的提问来源于stack exchange,提问作者ashrth
相关产品推荐
相关产品推荐

