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),必须用函数式更新的写法:
不然很可能拿到旧的state值,导致计算错误。this.setState(prevState => ({ movement: prevState.movement + deltaX }))
第二种:直接用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
相关产品推荐
相关产品推荐

