React 18中出现Cannot read properties of undefined (reading 'map')错误求助
问题排查与修复方案
根据你提供的代码和错误信息,应用崩溃的核心原因是属性访问错误、拼写失误以及初始值设置不当,以下是具体修复步骤:
1. 核心崩溃原因:属性访问错误
你的组件错误地将setter方法/动作当作存储选中状态的属性访问,同时存在大小写拼写错误:
- 在
BrandBar中,dye.SetSelectedBrand.Id是错误写法:SetSelectedBrand是设置选中品牌的方法/动作,并非存储选中结果的属性,应改为访问dye.SelectedBrand(对应store中_SelectedBrand的getter)Id大小写错误,需改为小写的id
- 在
TypeBar中,dye.SetSelectedType.id是错误写法:SetSelectedType是设置选中类型的方法/动作,应改为访问dye.SelectedType属性
2. 拼写错误修复
BrandBar组件中style={{cursor:'poiinter'}}的poiinter拼写错误,改为pointer才能正常生效鼠标悬停样式。
3. 初始值优化(避免潜在异常)
DyeStore中_SelectedType和_SelectedBrand初始化为空对象{},首次渲染时dye.SelectedType.id会返回undefined,虽不会直接崩溃,但会导致选中状态判断异常。建议初始化为列表中的第一个项:
constructor(){ this._Types = [{id:1,name:'Акриловая'}] this._Brands = [{id:1,name:'Самсунг'}] this._Dyes = [{id:1,name:'Самсунг',price: 2400,rating:5}] // 初始选中第一个类型和品牌 this._SelectedType = this._Types[0] this._SelectedBrand = this._Brands[0] makeAutoObservable(this) }
4. 确保getter/setter定义正确
确认DyeStore中正确定义了getter和setter(符合Mobx的可观察对象规范),标准写法如下:
import { makeAutoObservable } from "mobx" export default class DyeStore{ constructor(){ this._Types = [{id:1,name:'Акриловая'}] this._Brands = [{id:1,name:'Самсунг'}] this._Dyes = [{id:1,name:'Самсунг',price: 2400,rating:5}] this._SelectedType = this._Types[0] this._SelectedBrand = this._Brands[0] makeAutoObservable(this) } // Getters get Types() { return this._Types } get Brands() { return this._Brands } get SelectedType() { return this._SelectedType } get SelectedBrand() { return this._SelectedBrand } // Setters set SelectedType(type) { this._SelectedType = type } set SelectedBrand(brand) { this._SelectedBrand = brand } }
修复后的组件代码
修复后的BrandBar
const BrandBar = observer(() => { const {dye} = useContext(Context) return ( <Form className='d-flex'> {dye.Brands.map(brand=> <Card key={brand.id} className="mt-2" onClick={()=> dye.SelectedBrand = brand} border={brand.id === dye.SelectedBrand.id ? 'danger' : 'light'} style={{cursor:'pointer'}} > {brand.name} </Card> )} </Form> ); })
修复后的TypeBar
const TypeBar = observer(() => { const {dye} = useContext(Context) return ( <ListGroup> {dye.Types.map( type => <ListGroup.Item style={{cursor: 'pointer'}} active={type.id === dye.SelectedType.id} onClick={() => dye.SelectedType = type} key={type.id} > {type.name} {/* 补充之前缺失的类型名称渲染 */} </ListGroup.Item> )} </ListGroup> ); })
注:TypeBar组件中补充了{type.name},否则列表项会显示为空。
内容的提问来源于stack exchange,提问作者zavaryxa
相关产品推荐
相关产品推荐

