V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bthulu
V2EX  ›  React

react 的 setState 用来自增, 是线程安全的吗?

  •  
  •   bthulu · 2024-05-05 16:39:51 +08:00 · 3209 次点击
    这是一个创建于 409 天前的主题,其中的信息可能已经有所发展或是发生改变。

    从后台订阅 websocket, 然后自增本地 state.

    如果后台同时发了多个请求过来要求自增 state, 会出现线程安全问题吗?

    13 条回复    2024-05-07 08:38:35 +08:00
    yidadaa
        1
    yidadaa  
       2024-05-05 17:09:57 +08:00   ❤️ 7
    js 是单线程。
    foolishcrab
        2
    foolishcrab  
       2024-05-05 17:22:29 +08:00 via iPhone
    用接收函数那个重载
    thinkershare
        3
    thinkershare  
       2024-05-05 17:28:58 +08:00
    不会,浏览器上的 JS 是单线程的,运行在一个消息事件循环里面,不可能有并行问题。如果有并行问题,JS 就需要提供同步的原语,但实际 JS 并没有这个玩意,也没有支持它的标准库接口。
    epiloguess
        4
    epiloguess  
       2024-05-05 17:44:44 +08:00
    react 的 state 是通过闭包来实现的,理论上线程安全,但是有一些要注意
    1,使用 state 的更新函数来获取和更新 state 的最新值,否则 react 的批处理可能会导致一些错误
    2.将 state 的改变尽量控制在一个小的组件里,react 可能不会立即清除你之前的状态除非组件被卸载,对于一个较大的组件,短时间大量的更新可能会导致内存方面的问题
    3.建议使用全局状态,本地存储,asynclocalstorage(服务端渲染)来解决问题
    userdhf
        5
    userdhf  
       2024-05-05 18:17:44 +08:00
    你这个问题,让我想起之前很早写过的 bug ,a 组件开定时器轮询接口,然后 a 组件在 x 、y 两个页面上均被使用,然后 x 页面发出的请求,因为网络延时,在 y 页面上渲染...不知道是不是你这种类似的问题,
    我使用 axios ,每次轮询前先 abort 掉前一个请求;或者 a 组件放在 state 中,渲染这个 state
    totoro52
        6
    totoro52  
       2024-05-05 19:06:26 +08:00
    JS 都没多线程概念哪来的安全不安全🤡
    codehz
        7
    codehz  
       2024-05-05 22:08:56 +08:00
    websocket 连接你也做不到同时发啊。。。
    yuankui
        8
    yuankui  
       2024-05-06 08:08:20 +08:00
    你可以这样就安全了
    ```
    setState(prev => prev + 1)
    ```
    ZnductR0MjHvjRQ3
        9
    ZnductR0MjHvjRQ3  
       2024-05-06 10:19:23 +08:00
    不要学个新词就乱用 , 你咋更都是由前后顺序的
    ColdBird
        10
    ColdBird  
       2024-05-06 11:37:14 +08:00
    自增的场景是什么?把数据直接写到 state 里然后取 state 的数组长度不就可以了吗
    bthulu
        11
    bthulu  
    OP
       2024-05-06 14:50:55 +08:00
    @ColdBird 场景很简单, 后台每生成一条日志就发到前端, 前端按时间倒序将日志一条条显示出来, 最多显示最近的 45 条.
    react 里循环 div 需要给个 key. 已知后端不是我这个组的, 别人只发日志, 不会给你带个 id 过来.
    我当然也可以随便给个 key, 或者就用日志内容当 key, 但如果有自增, 不是性能更好么?
    StevenRCE0
        12
    StevenRCE0  
       2024-05-06 19:58:07 +08:00
    这个需求完全可以通过遍历的 index 来填充吧,毕竟数据变更触发重新渲染的时候这个循环也会跟着更新,不应该有冲突
    ColdBird
        13
    ColdBird  
       2024-05-07 08:38:35 +08:00
    @bthulu 如果数组顺序不变,你用 index 当 key 就行,如果顺序变了,你这个也没用。所以用 index 作 key 就行。如果对性能很在意,可以通过 timestamp+接收时 index 作 key (其实意义不大)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5845 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 02:09 · PVG 10:09 · LAX 19:09 · JFK 22:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.