react 的 setState 用来自增, 是线程安全的吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bthulu
V2EX    React

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

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

    从后台订阅 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
    MIUIOS
        6
    MIUIOS  
       2024-05-05 19:06:26 +08:00
    JS 都没多线程概念哪来的安全不安全
    codehz
        7
    codez  
       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     Solana     1032 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 22:55 PVG 06:55 LAX 15:55 JFK 18:55
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86