React类组件转函数组件报错排查:map调用失败与props取值异常

你遇到的所有报错和不符合预期的问题,根源都是函数组件的props规则、函数定义逻辑写错了,按以下步骤逐一修正即可:
1. 修正Home组件
你之前的错误点:
- 函数组件第一个参数永远是props对象,不能直接写
(term, location) searchYelp直接在组件根执行,导致一渲染就触发请求,传给SearchBar的是Promise不是可调用函数- 传给BusinessList的prop名写错,用了
business而非原逻辑的businesses
修正后代码:
import React, { useState } from "react"; import BusinessList from '../../../src/components/BusinessList/BusinessList'; import SearchBar from '../../../src/components/SearchBar/SearchBar'; import Yelp from '../../util/yelp'; const Home = () => { const [businesses, setBusinesses] = useState([]); // 定义为可调用函数,和原类组件逻辑对齐 const searchYelp = (term, location, sortBy) => { Yelp.searchYelp(term, location, sortBy).then(res => { // 兜底空数组,避免接口返回空时后续map报错 setBusinesses(res || []) }) } return ( <> <SearchBar searchYelp={searchYelp} /> <BusinessList businesses={businesses} /> </> ) } export default Home;
2. 修正BusinessList组件
你之前的错误点:
- 同样是props规则问题,把props对象直接当成了businesses数组
- map遍历的时候没有写return,导致返回undefined无法渲染组件
修正后代码:
import React from "react"; import './BusinessList.css'; import Business from '../Business/Business'; // 解构props中的businesses数组 function BusinessList({ businesses }) { return ( <div className="BusinessList"> { (businesses || []).map(business => { // 必须写return返回Business组件 return <Business key={business.id} business={business} /> }) } </div> ) }; export default BusinessList;
3. 修正Business组件
你之前的错误点:
- 没有解构props,直接把props对象命名为business,所以只能通过
business.business.xxx取值
修正后代码:
import React from "react"; import './Business.css'; // 解构props中的business属性,就可以和类组件一样直接调用属性 const Business = ({ business }) => { return ( <div className="Business"> <div className="image-container"> <img src={business.imageSrc} alt={business.imageSrc} /> </div> <h2>{business.name}</h2> <div className="Business-information"> <div className="Business-address"> <p>{business.address}</p> <p>{business.city} {business.state} {business.zipCode}</p> </div> <div className="Business-reviews"> <h3>{business.category}</h3> <h3 className="rating">{business.rating}</h3> <p>{business.reviewCount} reviews</p> </div> </div> </div> ) }; export default Business;
4. 修正SearchBar组件
你之前的错误点:
- 排序选择逻辑写错,没有拿到点击的排序值,无法更新sortBy状态
- 搜索触发时没有把sortBy参数传给父组件的searchYelp方法
- return中多余渲染了
{props.searchYelp},会显示函数的字符串内容
核心修正点:
// 接收点击的排序选项值 const handleSortByChange = (sortByOption) => { setSortBy(sortByOption) } const renderSortByOptions = () => { return Object.keys(sortByOptions).map(sortByOption => { let sortByOptionValue = sortByOptions[sortByOption] return <li className={sortBy === sortByOptionValue ? 'active' : ''} // 绑定要传递的排序参数 onClick={() => handleSortByChange(sortByOptionValue)} key={sortByOptionValue}> {sortByOption} </li>; }) } const handleSearch = (event) => { event.preventDefault() // 补全sortBy参数,和原逻辑对齐 props.searchYelp(term, location, sortBy) } // return中删除{props.searchYelp},调用renderSortByOptions不需要传参
报错原因说明
- Cannot read properties of undefined (reading 'map'):要么是接口返回空没有兜底为空数组,要么是把props对象当成数组调用了map方法
- Businesses.map is not a function:同上,props是对象类型,不存在map方法
- 需要写
business.business.xxx:没有解构props的属性,函数组件第一个参数永远是props对象,你传的prop叫business,所以props.business才是实际的业务数据对象
内容的提问来源于stack exchange,提问作者Halp_am_stuck
相关产品推荐
相关产品推荐

