React删除表格行报错‘Cannot read property 'deleteProduct' of undefined’求解决
解决React删除表格行时的
Cannot read property 'deleteProduct' of undefined错误及API删除优化方案 一、错误原因与修复方案
你遇到的这个报错,核心问题是map回调函数里的this指向不对。在this.state.UserData.map(function(item, key) { ... })中,普通function会创建独立的作用域,这里的this不再指向你的FetchedData组件实例,自然找不到deleteProduct方法。
修复方法(推荐第一种)
- 改用箭头函数作为map回调:箭头函数会自动继承外部作用域的
this,直接解决指向问题
{ this.state.UserData.map((item, key) => { return ( <tr key={key}> <td>{item.name}</td> <td>{item.department}</td> <td>{item.marks}</td> <td><span onClick={() => this.deleteProduct(item.id)}>Delete</span></td> </tr> ) }) }
- 给map方法传入第二个参数绑定
this:如果坚持用普通function,可以在map的第二个参数里指定回调的this指向组件实例
{ this.state.UserData.map(function(item, key) { return ( <tr key={key}> <td>{item.name}</td> <td>{item.department}</td> <td>{item.marks}</td> <td><span onClick={() => this.deleteProduct(item.id)}>Delete</span></td> </tr> ) }, this) }
附带的代码优化点
componentDidMount里的setState链式调用.catch是错误的,因为setState不返回Promise,要把catch移到fetch的then链后面:
componentDidMount(){ this.lookupInterval = setInterval(() => { fetch("https://www.veomit.com/test/zend/api/fetch.php") .then(response => response.json()) .then(result => { this.setState({ UserData: result }) }) .catch(error => { console.log("An error occurred while trying to fetch data: " + error); }); }, 500) }
- 组件卸载时记得清除定时器,避免内存泄漏:
componentWillUnmount() { clearInterval(this.lookupInterval); }
二、自定义API删除数据的简便方法
1. 使用axios简化请求(推荐)
axios是封装好的HTTP客户端,比原生fetch更简洁,自动处理JSON解析,错误逻辑更清晰。
首先安装axios:npm install axios
然后修改删除方法:
import axios from 'axios'; // 用箭头函数可以省去手动bind this的步骤 deleteProduct = async (userId) => { try { const response = await axios.post('https://www.veomit.com/test/zend/api/delete.php', { userId: userId }); // 用函数式setState,避免依赖旧state值的风险 this.setState(prevState => ({ response: response.data, UserData: prevState.UserData.filter(item => item.id !== userId) })); } catch (error) { this.setState({ error }); } }
2. 封装API请求函数(提升可维护性)
把所有API请求抽离到单独文件,比如api.js,方便统一管理和复用:
// api.js import axios from 'axios'; const API_BASE_URL = 'https://www.veomit.com/test/zend/api'; export const fetchUsers = () => axios.get(`${API_BASE_URL}/fetch.php`); export const deleteUser = (userId) => axios.post(`${API_BASE_URL}/delete.php`, { userId });
然后在组件中导入使用:
import { fetchUsers, deleteUser } from './api'; // 组件内的请求逻辑可以简化为: componentDidMount(){ this.lookupInterval = setInterval(async () => { try { const response = await fetchUsers(); this.setState({ UserData: response.data }); } catch (error) { console.log("Fetch error: " + error); } }, 500) } deleteProduct = async (userId) => { try { const response = await deleteUser(userId); this.setState(prevState => ({ response: response.data, UserData: prevState.UserData.filter(item => item.id !== userId) })); } catch (error) { this.setState({ error }); } }
内容的提问来源于stack exchange,提问作者Dev5
相关产品推荐
相关产品推荐

