React HOC无法解析传值:父组件传递坐标到子组件渲染报错
报错原因
你定义Direction的逻辑存在根本性错误:当前Direction是一个接收props后返回HOC生成的组件函数的普通函数,而非可直接渲染的React组件:
- 你当前的写法是
const Direction = (props) => compose(...)(组件),当你用<Direction name={'xxx'} />调用它时,返回值是未执行的组件构造函数,不是可渲染的JSX内容,因此React检测到你把函数作为子元素渲染,直接抛出对应警告。 - 同时存在两个额外逻辑漏洞:
googleMapURL用了双引号包裹模板字符串,里面的${key}不会被解析,需要替换为反引号DirectionsService.route是回调风格API,不会返回Promise,你后续挂载的.then()会直接报错。
修复方案
第一步:修正Direction的定义
去掉外层的(props) => 包裹,把静态配置和组件逻辑分离,修改后的代码如下:
// 先通过compose生成包装后的地图组件,这才是可直接渲染的React组件 const Direction = compose( withProps({ // 改用反引号包裹才能解析模板变量${key} googleMapURL: `https://maps.googleapis.com/maps/api/js?key=${key}&v=3.exp&libraries=geometry,drawing,places`, loadingElement: <div style={{ height: `100%` }} />, containerElement: <div style={{ height: `100%` }} />, mapElement: <div style={{ height: "100%", width: "100%", margin: "0px auto", position: "absolute" }} />, }), withScriptjs, withGoogleMap, lifecycle({ componentDidMount() { const DirectionsService = new window.google.maps.DirectionsService(); // 父组件传递的name参数从this.props取,不要从外层作用域取 const originLat = this.props.name; DirectionsService.route({ origin: new window.google.maps.LatLng(originLat,101.686855), destination: new window.google.maps.LatLng(3.148780599999999,101.6936573), waypoints: [{ location:new window.google.maps.LatLng(3.145832999999999,101.695556), stopover:false }], optimizeWaypoints: true, travelMode: window.google.maps.TravelMode.DRIVING, }, (result, status) => { if (status === window.google.maps.DirectionsStatus.OK) { this.setState({ directions: result, }); // 原then逻辑挪到回调内,因为route方法不返回Promise const route = result.routes[0]; console.log(route); alert(route.legs[0].distance.text); alert(route.legs[0].duration.text); } else { console.error(`error fetching directions ${result}`); } }) // 删除原来的.then调用,避免触发undefined调用then的报错 } }) )(props => <GoogleMap defaultZoom={7} defaultCenter={new window.google.maps.LatLng(3.139003,101.686855 )} > <Marker position={{ lat: 3.145832999999999, lng: 101.695556 }} /> <Details /> {props.directions && <DirectionsRenderer directions={props.directions} /> } </GoogleMap> );
第二步:修复App.js的重名问题
你当前App.js导出的组件和单独的FirstScreen组件重名,修改为正确的App组件即可:
export default function App() { return ( <div > <PassCords /> </div> ) }
第三步:实现传值触发重渲染需求
如果需要父组件修改坐标后子组件重新请求路线,只需把componentDidMount里的请求逻辑提取为公共方法,新增componentDidUpdate钩子判断坐标是否变化,变化时重新发起请求即可。
内容的提问来源于stack exchange,提问作者AMAN KUMAR
相关产品推荐
相关产品推荐

