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

React中用setState修改样式属性报错:Cannot read property 'state' of undefined

解决React中onScroll事件无法访问this.state的问题

别害羞!这种this指向的坑在React开发里太常见了,好多刚上手的开发者都会碰到,完全不用不好意思😉

问题原因

当你直接在DOM元素上绑定onScroll={this.handleScroll}时,事件触发时handleScroll函数内部的this并没有指向你的组件实例(在严格模式下会变成undefined),自然就会抛出Cannot read property 'state' of undefined的错误。

几种解决方案

1. 用箭头函数直接绑定事件

最简单的写法,在事件绑定的时候用箭头函数包裹,这样函数会继承外层的this(也就是组件实例):

<div onScroll={() => this.handleScroll()}>
  {/* 滚动内容 */}
</div>

// 对应的处理函数
handleScroll() {
  console.log(this.state.backgroundColor); // 现在能正常访问了
}

⚠️ 小提示:这种写法每次组件渲染都会创建一个新的箭头函数,性能敏感的场景(比如列表项)可能会有轻微影响,但大部分普通场景完全够用。

2. 在构造函数中手动bind this

这是比较经典的写法,在组件构造函数里一次性把handleScroll的this绑定到组件实例:

constructor(props) {
  super(props);
  this.state = { backgroundColor: 'white' };
  // 关键:手动绑定this
  this.handleScroll = this.handleScroll.bind(this);
}

handleScroll() {
  this.setState({ backgroundColor: 'blue' });
}

// 渲染时直接绑定函数
<div onScroll={this.handleScroll}>...</div>

这种写法不会重复创建函数,性能更友好,适合需要优化性能的场景。

3. Class Fields 箭头函数(React推荐的简洁写法)

利用ES6+的类属性语法,直接把处理函数写成箭头函数,这样函数的this会自动绑定到组件实例:

// 直接在类里定义箭头函数
handleScroll = () => {
  const scrollTop = event.target.scrollTop;
  this.setState({ 
    backgroundColor: scrollTop > 100 ? 'lightblue' : 'white' 
  });
}

// 渲染时直接使用
<div onScroll={this.handleScroll}>...</div>

这种写法既简洁又不用手动处理this绑定,是现在React开发中比较常用的方式。

4. 函数组件用Hooks(无this烦恼)

如果你用的是函数组件,那根本不用考虑this的问题,直接用useState和普通函数就行:

import { useState } from 'react';

function ScrollableDiv() {
  const [backgroundColor, setBackgroundColor] = useState('white');

  const handleScroll = (event) => {
    const scrollTop = event.target.scrollTop;
    setBackgroundColor(scrollTop > 100 ? 'lightblue' : 'white');
  };

  return (
    <div
      onScroll={handleScroll}
      style={{
        height: '400px',
        overflowY: 'auto',
        backgroundColor: backgroundColor,
        transition: 'background-color 0.3s'
      }}
    >
      <div style={{ height: '1000px', padding: '20px' }}>
        滚动我看看背景色变化~
      </div>
    </div>
  );
}

完整示例代码(Class组件版本)

import React from 'react';

class ScrollDiv extends React.Component {
  state = {
    backgroundColor: 'white'
  };

  handleScroll = (event) => {
    const scrollTop = event.target.scrollTop;
    this.setState({
      backgroundColor: scrollTop > 100 ? 'lightblue' : 'white'
    });
  };

  render() {
    return (
      <div
        onScroll={this.handleScroll}
        style={{
          height: '400px',
          overflowY: 'auto',
          backgroundColor: this.state.backgroundColor,
          transition: 'background-color 0.3s ease'
        }}
      >
        <div style={{ height: '1000px', padding: '20px', fontSize: '18px' }}>
          向下滚动超过100px,背景色会变成浅蓝色哦😎<br/>
          滚回去又会变回白色~
        </div>
      </div>
    );
  }
}

export default ScrollDiv;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:27:55