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

React组件中this的扩展性使用合理性探讨

React中直接使用this存储变量 vs 依赖state的场景与优缺点

你提的这个问题真的很典型——很多刚接触React的开发者都会在处理这类触摸、拖拽交互时纠结:到底哪些状态该放进state,哪些可以直接挂在组件实例上。先给你明确一个核心原则:React的设计核心是「状态驱动UI」,只有当变量需要触发UI更新时,才应该放进state;纯临时的中间值,完全可以用this(函数组件里对应useRef)来存储。

接下来分两部分分析你的两种写法:

第一种:用state存储触摸相关状态

先看你的第一段代码,把movement、touchStartX这些都放进state里,这是React的常规写法,适合的场景和优缺点如下:

优点

  • 符合React设计模式:state的变化会自动触发组件重渲染,如果你需要在render里根据movement实时更新滑块的位置(比如给div加transform样式),这种方式能保证UI和状态完全同步,不用手动处理更新逻辑;
  • 可追踪与调试:React DevTools会记录state的每一次变化,你可以清晰看到触摸过程中状态的更新轨迹,调试起来非常方便;
  • 生命周期兼容:React的生命周期钩子(比如shouldComponentUpdate、componentDidUpdate)能感知到state的变化,方便你做性能优化或者副作用处理。

缺点

  • 可能触发过多重渲染:在touchMove事件里频繁调用setState,虽然React会做批量更新优化,但极端情况下还是可能导致性能问题;
  • 异步更新的坑:state的更新是异步的,如果你的逻辑依赖前一次的state值(比如计算累计的movement),必须用函数式更新的写法:
    this.setState(prevState => ({
      movement: prevState.movement + deltaX
    }))
    
    不然很可能拿到旧的state值,导致计算错误。

第二种:直接用this存储变量

你的第二段代码把这些触摸相关的值直接挂在组件实例上,这种方式并不少见,但只适合特定场景:

优点

  • 性能更优:直接赋值不会触发重渲染,对于那些只是用来做中间计算、不需要实时反映到UI上的临时值(比如触摸起始位置、是否正在触摸的标记),这种方式更轻量;
  • 同步更新:不需要担心state异步更新的问题,赋值后立刻就能拿到最新值,逻辑更直观。

缺点

  • 脱离React状态体系:如果之后你需要在render里用到这些值(比如实时显示滑块位置),UI不会自动更新,除非手动调用forceUpdate——但forceUpdate是不推荐的,它会跳过React的性能优化逻辑,破坏组件的可预测性;
  • 调试与维护困难:这些变量不会出现在React DevTools里,出问题时很难追踪它们的变化;
  • 状态重置风险:组件卸载后,如果还有异步操作(比如延迟的触摸事件回调)修改this上的变量,可能导致内存泄漏或者报错;而且组件重新挂载时,这些变量不会自动重置,可能残留旧状态。

给你的具体建议

回到你的Slider组件:

  • 如果你的滑块需要实时跟随触摸移动(也就是render里要用到movement来更新样式),那必须把movement放进state,而touchStartX、beingTouched这类中间值可以考虑放在this上,减少state的更新次数;
  • 如果只是在touchEnd时才处理最终的滑动结果,不需要实时更新UI,那所有触摸过程中的临时值都可以挂在this上,只把最终的结果(比如滑块的最终位置)放进state。

另外注意你第二段代码里的一个笔误:handleTouchMove里写了e.targetTouches[0].clientX - this.state.touchStartX,但这个写法里touchStartX是挂在this上的,应该改成this.touchStartX,不然会报错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:24:40