修复 '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}))
}
}
问题回顾
你知道为什么我收到 this.handleSubmit
中的 this
未定义的错误吗?
哪个文件 --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>
背景
我正在为学校做一个期末项目,该项目使用卡片显示电视列表 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}))
}
}
问题回顾
你知道为什么我收到
this.handleSubmit
中的this
未定义的错误吗?哪个文件 --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>