React 踩坑之旅(map函数下this.类函数)

本文深入探讨了React中组件状态管理和事件处理的最佳实践。详细解析了如何在构造函数中绑定事件处理器,解决this指向问题,以及在组件内部正确处理状态更新的方法。同时,文章还提供了如何在列表渲染中正确绑定事件处理器的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:create-react-app搭建react程序
示例组件如下:

const list = [
  {
    title: 'React',
    url: 'http://facebook.github.io/react/',
    author: 'daxue',
    num_components: 3,
    points: 4,
    objectID: 0,
  },
  {
    title: 'Redux',
    url: 'http://facebook.github.io/reactjs/redux/',
    author: 'Dan Abramov, Andrew Clark',
    num_components: 2,
    points: 5,
    objectID: 1,
  }
];
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: list
    };
    this.onDismiss = this.onDismiss.bind(this);
  }
  render() {
    return <div className="list-div">
      {this.state.list.map(function (item) {
        const onHandleDismiss = ()=>{
          this.onDismiss(item.objectID);
        };
        console.log(item.objectID+Math.random());
        return <div key={item.objectID+Math.random()}>
          <span><a href={item.url}>{item.title}</a></span>
          <span>{item.author}</span>
          <span>{item.num_components}</span>
          <span>{item.points}</span>
          <button onClick={onHandleDismiss}>删除</button>
        </div>
      },this)}
    </div>
  }
  onDismiss(objectID) {
    const updatedList = this.state.list.filter(item => item.objectID !== objectID);
    this.setState({list: updatedList})
  }

}

##### 注意点1

众所周知:类函数并不会绑定到实例上去。(只有es6的箭头函数是绑定到类实例上去的,因为箭头函数中的this绑定上下文环境)

所以要手动绑定this到类函数上去
有代码:this.onDismiss = this.onDismiss.bind(this);

在构造器中加载,只有组件被第一次创建的时候,才会被调用,即是,组件类实例化的时候,绑定类方法到类实例上去。

##### 注意点2
但是在本例中,删除按钮监听一个点击事件。onClick={function类型}
所以不能直接调用onClick={this.onDismiss(item.objectID)}

此时{}中是一个函数表达式,会在加载到浏览器时候,就被执行,所以点击按钮,将没有反应。
只能传入onClick={this.onDismiss},这个时候,传入的就是一个函数了,在浏览器加载的时候,不会被立刻执行。
但是此例中需要传一个参数objectID
解决方案,在外面再包装一层函数,即是onClick={ () => this.onDismiss(item.objectID)}

##### 注意点3
这个时候貌似没有问题了,但是点击按钮,浏览器报错,
Uncaught TypeError: Cannot read property 'onDismiss' of undefined
很显然,这是说,onDismiss属性未定义,或者没有,但是博主的onDismiss函数明明已经定义了,并且在构造器中也绑定了this

终于到最坑的地方了,话不多说,看webStorm的一个检验的警告信息:

Potentially invalid reference access to a class field via 'this.' of a nested function

翻译一下(通过嵌套函数的“this.”对类字段的引用访问可能无效)

终于明白了,因为要传递item.objectID,所以只能在map()函数里面调用this.onDismiss()函数,
map函数的回调函数中 ---------------------- 匿名函数
很显然,找不到属性onDismiss是因为,this没有指向类的实例。当然是没有这个属性的。
经过一番周折,想着怎么把this给传进map函数里面。

让我们来看一下map函数

map(function(item,index,arr),thisValue)
请注意,几乎很少用的thisValue参数的解释:

可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。

解决方案,把指向类实例的this传进map()方法。如此以来,map中的this指向类实例。
解决问题,(书上的这个坑,喜提彩蛋。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值