You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件传递函数字典报错:无法读取undefined的select属性

问题分析与解决

我在App组件中定义了SelectCard和DiscardCard两个函数,随后将这两个函数以对象形式通过onPress属性传递给Card组件,代码如下:

<Card 
  key={el.key} 
  item={el} 
  onPress={{
      select: () => SelectCard(el.key),
      discard: () => DiscardCard(el.key)
  }}
/>

但在Card组件中尝试通过props.onPress.select访问该函数时,出现了如下错误:

react-dom.development.js:18687 The above error occurred in the <Card> component:

    at Card (http://localhost:5174/src/components/Card.jsx?t=1670102247232:33:48)
    at div
    at div
    at div
    at App (http://localhost:5174/src/App.jsx?t=1670102247232:24:31)

react-dom.development.js:26923 Uncaught TypeError: Cannot read properties of undefined (reading 'select')
    at Card (Card.jsx:28:32)
    at renderWithHooks (react-dom.development.js:16305:18)
    at mountIndeterminateComponent (react-dom.development.js:20074:13)
    at beginWork (react-dom.development.js:21587:16)
    at beginWork$1 (react-dom.development.js:27426:14)
    at performUnitOfWork (react-dom.development.js:26557:12)
    at workLoopSync (react-dom.development.js:26466:5)
    at renderRootSync (react-dom.development.js:26434:7)
    at recoverFromConcurrentError (react-dom.development.js:25850:20)
    at performConcurrentWorkOnRoot (react-dom.development.js:25750:22)

完整代码

App组件

import { useState } from 'react'
import reactLogo from './assets/react.svg'
import Card from './components/Card'
import data from "./assets/data.json"
import {nanoid} from "nanoid"

function App() {
  const [people, setPeople] = useState(data['people'].map(
    el=>{
      return {
        ...el,
        'key' : nanoid(),
      }
    }
  ))

  const [myCard, setMyCard] = useState(
    {
      "name":"Name and Surname",
      "img":"https://i.picsum.photos/id/1070/200/300.jpg?hmac=dJNTYlLwT_0RupxbJNbw5Wj-q2cCTB4Xh-GqWRofIIc",
      "description": "This is a silly descriptionhis is a silly descriptionhis is a silly description",
      'key' : nanoid(),
      "selected":false,
      "active":true,
    }
  )


  function SelectCard(CardKey){
    console.log('SelectCard')
    setPeople(oldPeople=>{
      return oldPeople.map(el=>{

        return el.key === CardKey
                ? { ...el, 'state': el.state === 'active'?'selected': 'active'}
                : { ...el, 'state':'active'}
          })
    })
  }

  function DiscardCard(CardKey){
    console.log('DiscardCard')
    setPeople(oldPeople=>{
      return oldPeople.map(el=>{
        return el.key === CardKey
                ? { ...el, 'state': el.state === 'discarded'?'active': 'discarded'}
                : { ...el}
          })
    })
  }

  const cards = people.map(el=>{
    return <Card 
            key = {el.key} 
            item={el} 
            onPress={{
                select : ()=>SelectCard(el.key),
                discard : ()=>DiscardCard(el.key)
          }}
          />
  })

  
  return (
    <div className="App">
      <div className='container'>
        <div className='left'>
          <div className='cards'>
            {cards}
          </div>
        </div>
        <div className = 'right'>
          <h4>You are: </h4>
          <Card key = {myCard.key} item={myCard}/>
        </div>
     </div>
     
    </div>
  )
}

export default App

Card组件

import { useState } from 'react'

function Card(props) {
  //const [count, setCount] = useState(0)

  function getClassName(state) {
    switch (state) {
      case "active":
        return "";
      case "selected":
        return "overlay-selected";
      case "discarded":
        return "overlay-discarded";
      case "complete":
        return "overlay-complete";
      default:
        return "";
    }
  }



  const className = `card ${getClassName(props.item.state)}`

  return (
    <div 
        className={className} 
        onClick={props.onPress.select}>
        <img className='card-img' alt='Card Image' src={props.item.img} />
        <h3 className='card-title'>{props.item.name} </h3>
        { props.item.state === 'selected' ? 
        
            <div className='card-cta'>
                <button 
                    className='btn btn-back'
                    onClick={ props.item.selected ?  (event)=>
                        { 
                            props.onPress.select
                            //event.stopPropagation()
                        }
                         : ()=>{}}
                >Back</button>
                <button 
                    className='btn btn-discard'
                    onClick={ 
                        (event) =>{
                            //event.stopPropagation()
                            props.onPress.discard 
                            console.log('called me')
                            }
                        }
                >Discard</button>
            </div>
        : 
        <p className='card-description'>{props.item.description} </p>  
    
        }
        
    </div>
  )
}

export default Card

错误原因

  1. 缺失onPress属性传递:在App组件右侧区域渲染myCard对应的Card组件时,没有传入onPress属性,导致该Card实例的props.onPress为undefined,访问props.onPress.select时直接抛出TypeError。
  2. 函数未实际调用:Card组件按钮的点击事件中,仅引用了函数(如props.onPress.select),但未执行函数,需要通过()触发调用。

解决方案

1. 给右侧Card补充onPress属性

如果右侧Card不需要操作逻辑,可传入空对象作为默认值;如果需要对应逻辑,传入针对myCard的处理函数:

// 示例:传入空对象避免报错
<Card key={myCard.key} item={myCard} onPress={{select: () => {}, discard: () => {}}}/>

2. 修复函数调用问题

在Card组件的按钮点击事件中,将函数引用改为调用形式:

// Back按钮
<button 
  className='btn btn-back'
  onClick={props.item.selected ? (event) => { 
    props.onPress.select(); // 加上()执行函数
    // event.stopPropagation()
  } : () => {}}
>Back</button>

// Discard按钮
<button 
  className='btn btn-discard'
  onClick={(event) => {
    // event.stopPropagation()
    props.onPress.discard(); // 加上()执行函数
    console.log('called me')
  }}
>Discard</button>

3. 可选:给Card组件设置props默认值

为避免后续未传属性导致的报错,可在Card组件中设置默认props:

function Card(props) {
  // 解构时设置默认值
  const { onPress = { select: () => {}, discard: () => {} }, item } = props;
  // ... 其他代码
}

// 或者使用defaultProps
Card.defaultProps = {
  onPress: {
    select: () => {},
    discard: () => {}
  }
};

内容的提问来源于stack exchange,提问作者giaggi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 19:05:24