react hook 的一个问题, useEffect 内部,为什么 可以调用 setxxx 方法? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yazoox
V2EX    React

react hook 的一个问题, useEffect 内部,为什么 可以调用 setxxx 方法?

  •  
  •   yazoox 2020-11-0 14:49:25 +08:00 3525 次点击
    这是一个创建于 1801 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在学习 react hook 经常看到这样的写法:

    import { getname } from "..."; my_compOnent= (props) => { const [name, setName] = useState("yazoox"); clickme = () => { const newname = getname(); setName(newname); } useEffect(() => { // call API getname,每次调用,都会随机拿一个名字 const newname = getname(); setName(newname); }, [name]); return ( <div>{name}</div> <div> <button Onclick={clickme()} >click me</button> </div> ); } 

    useEffect 是在 component mount 后调用的(相当于 componentDidMount/DidUpdate)。

    两个问题:

    1. mount 完成后,useEffect 触发了,调用 getname 得到了新的名字,再用 setName 更新这个 state,那就是说 UI 又要 update 。这样的话,不会再触发 useEffect 么?再 setName 一次,dependency - name 又变化了,这个 effect 就会再触发啊。......

    注:这种情况,我能想到的实际场景,就是打开网站,界面先画出来,但是图片还在后台加载。等图片加载完成了,继续画。

    1. 另外一个例子,我点击 button,刷新了一次 name,userEffect 会不会触发啊?

    还是说,react hook 设计上,保证了在 useEffect 内部,setXXX 即使是 dependency,也不会重复触发?

    谢谢!

    p.s. 有没有 react 可以 online 编辑 /实践的网站? codepen.io 需要 VIP 才可以......

    第 1 条附言    2020-11-05 16:26:02 +08:00
    注:
    我是学习过程中,看到这个帖子,有感而发,才发的这个帖子。
    https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately
    17 条回复    2020-11-06 13:57:06 +08:00
    star7th
        1
    star7th  
       2020-11-05 15:09:11 +08:00
    提供一下原教程链接看看。谁知道这是源码还是经过你加工出来的问题代码
    syfless
        2
    syfless  
       2020-11-05 15:12:10 +08:00
    这段 useEffect 里的代码意义不明,本来就是 name 变化之后执行 useEffect 里的副作用,但 useEffect 又放了无条件改变 name 的代码,这就死循环了,不过好像 useEffect 里面会自动检测会不会死循环,顶多是执行几十次就停了
    codesandbox.io 可以
    shenyu1996
        3
    shenyu1996  
       2020-11-05 15:12:29 +08:00
    [name] => []
    CptDoraemon
        4
    CptDoraemon  
       2020-11-05 15:13:53 +08:00 via Android
    setState's identity is guaranteed to be stable over components's life cycle. 文档里说的
    easonHHH
        5
    easonHHH  
       2020-11-05 15:21:52 +08:00
    当 name 发生变化后,然后就从 api 获取一个 new name 然后赋值到 name ?
    anjianshi
        6
    anjianshi  
       2020-11-05 15:31:01 +08:00
    按上面的代码,useEffect 确实没啥用,而且会死循环
    u6pM63mMZ34z32cE
        7
    u6pM63mMZ34z32cE  
       2020-11-05 15:39:31 +08:00
    <button Onclick={clickme()} >click me</button>
    这行代码没看懂 clickme()不是 undefined 吗
    dartabe
        8
    dartabe  
       2020-11-05 15:48:33 +08:00
    建议多看看好点的教程 有点不知所云

    写 Hooks 的时候把 eslint 用起来
    zhuweiyou
        9
    zhuweiyou  
       2020-11-05 15:49:57 +08:00
    1. 你这段 useEffect 多余, 可以删了.
    2. Onclick={clickme()} 应该改成 Onclick={clickme}
    xingguang
        10
    xingguang  
       2020-11-05 16:11:41 +08:00
    感觉不太对,我觉着这里不应该依赖 name,这里应该是要给个默认值吧。把依赖去掉比较合理
    alexkuang
        11
    alexkuang  
       2020-11-05 16:45:03 +08:00
    codepen 免费版可以用 react 的,通过 cdn 导入
    onfuns
        12
    onfuns  
       2020-11-05 16:51:00 +08:00
    你这个无限循环了,如果只 mount 后进入执行赋值 name,那么依赖设置空数组即可。如果对 name 监听,可以再写一个 useEffect 对 name 监听,要么定义一个变量控制
    KuroNekoFan
        13
    KuroNekoFan  
       2020-11-05 18:02:17 +08:00
    可以用 codesandbox...
    auroraccc
        14
    auroraccc  
       2020-11-05 18:15:38 +08:00
    你那个 useEffect 内部都没有使用 name 为什么要依赖 name,依赖应该是[]
    TabGre
        15
    TabGre  
       2020-11-05 20:09:32 +08:00   1
    https://overreacted.io/

    文章就得去看这个大神
    azcvcza
        16
    azcvcza  
       2020-11-06 09:10:24 +08:00
    你这和原先 componentWillRecieveProps 里把 拿来的 props 赋值给 state 引起无限循环差不多
    jingcoco
        17
    jingcoco  
       2020-11-06 13:57:06 +08:00
    3 楼靠谱.....useEffect 的第二个参数
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2738 人在线   最高记录 6679       Select Languag
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 11:38 PVG 19:38 LAX 04:38 JFK 07:38
    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