修复 'Cannot read property handleClick of undefined error'(以及与从 DOM 中删除项目相关的问题)

Fix a 'Cannot read property handleClick of undefined error' (and issues related to deleting an item from the DOM)

背景

我正在为学校做一个期末项目,该项目使用卡片显示电视列表 shows/programs。我正在尝试设置一种删除卡的方法。我正在尝试让这个删除在我的前端工作。我花了很长时间研究这个问题,以至于我现在想到的每一个解决方案似乎都是对的和错的。

首先,我解决了 programId 未定义的问题。现在我不知道如何让我的 this in this.handleClick 工作。 让我觉得我可能需要使用绑定。但我不确定。

代码

这是我的 Program.js 文件的一部分,其中对卡片进行了样式设置,并传递了道具以填充名称、网络和图像等字段。我使用 props.match.params 是因为我已经实现了 React Router 并且需要访问每张卡片的数据以获取其中的三元语句。编辑:Program.js 是一个功能组件。我添加了 link.

let handleClick = (id) => {
    this.props.deleteProgram(id)

  }

let program = props.program ? props.program : props.programs[props.match.params.id - 1]
let programId = program.id

    return(
        <Grid.Column>
          <Card onClick={(_) => this.handleClick(programId)}>
            <Image src={program ? program.image : null} wrapped ui={false} />
            <Card.Content>
              <Card.Header>{program ? program.name: null}</Card.Header>
              <Card.Meta>
                <span className='date'>{program ? program.network : null 
                </span>
              </Card.Meta>

这是我的 Programs.js 文件,它创建了每个程序组件。我不确定我是否应该在我创建每个程序的文件中导入我的 {deleteProgram} action/function,或者我是否需要直接在程序中导入它。 编辑:Programs.js 是一个功能组件。我添加了 link.

        <Grid columns='six' divided='vertically'>
          <Grid.Row >
              {props.programs.map((program) => <Program key={program.id} program={program} />)}
          </Grid.Row>
        </Grid>

这是 programsReducer 文件,其中包含用于删除程序的 case 语句。

case 'DELETE_PROGRAM':
      const programs = state.programs.filter(program => program.id !== 
          action.id)
      return {programs}

这是我的 deleteProgram action/function.

return (dispatch) => {
    fetch(`http://localhost:3000/api/v1/programs/${id}`,{
      method: 'DELETE',
      headers: {'Content-Type': 'application/json'}
    })
    .then(res => res.json())
    .then(res => dispatch({type: 'DELETE_PROGRAM', id: id}))
  }
}

问题回顾

  1. 你知道为什么我收到 this.handleSubmit 中的 this 未定义的错误吗?

  2. 哪个文件 --Programs.js(带有 .map)或 Program.js(每个单独的卡 -- 我应该导入我的 {deleteProgram} function/action 进入?

奖金回合

如果没记错的话,我要把这个onClick方法放在整张卡片上。我很乐意在卡片中制作的删除按钮上调用它。有人可以确认这是否正确吗?

非常感谢您的宝贵时间! :-)

问题1:绑定this的方法之一是在组件的构造函数中。

this.function = this.function.bind(this);

关于问题 2:我会将 deleteCardFunction() 作为每张卡片的道具发送。然后在你要删除的时候从这个id的卡片中调用。

因为这是一个函数组件,而不是 class,所以你不应该在那里使用它。只需使用函数名称即可。

<Card onClick={() => handleClick(programId)}>

甚至可以在不绑定它的情况下工作,因为您已经在函数声明中使用箭头函数来完成它:

<Card onClick={handleClick(programId)}>

我会将 delete 导入 Program.js,因为在其中包含删除按钮很有意义。

另一个巧妙的技巧,而不是使用 ? : shorthand, 你可以使用 || 做的更短,比如:

let program = props.program || props.programs[props.match.params.id - 1]

为了能够在卡片中放置另一个 onClick,您必须阻止事件冒泡,在删除方法之前或内部调用 event.stopPropagation()。

将您的代码更改为以下内容:

let handleClick = (id) => {
  props.deleteProgram(id)

  }

let program = props.program ? props.program : props.programs[props.match.params.id - 1]
let programId = program.id

return(
    <Grid.Column>
      <Card onClick={(_) => handleClick(programId)}>
        <Image src={program ? program.image : null} wrapped ui={false} />
        <Card.Content>
          <Card.Header>{program ? program.name: null}</Card.Header>
          <Card.Meta>
            <span className='date'>{program ? program.network : null 
            </span>
          </Card.Meta>