V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
yazoox
V2EX  ›  React

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

  •  
  •   yazoox · Nov 5, 2020 · 3885 views
    This topic created in 2002 days ago, the information mentioned may be changed or developed.

    最近在学习 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 才可以......

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

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

    文章就得去看这个大神
    azcvcza
        16
    azcvcza  
       Nov 6, 2020
    你这和原先 componentWillRecieveProps 里把 拿来的 props 赋值给 state 引起无限循环差不多
    jingcoco
        17
    jingcoco  
       Nov 6, 2020
    3 楼靠谱.....useEffect 的第二个参数
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2455 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 63ms · UTC 04:10 · PVG 12:10 · LAX 21:10 · JFK 00:10
    ♥ Do have faith in what you're doing.