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

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

  •  
  •   yazoox · 28 天前 · 1389 次点击

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

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

    文章就得去看这个大神
    azcvcza
        16
    azcvcza   27 天前
    你这和原先 componentWillRecieveProps 里把 拿来的 props 赋值给 state 引起无限循环差不多
    jingcoco
        17
    jingcoco   27 天前
    3 楼靠谱.....useEffect 的第二个参数
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3577 人在线   最高记录 5298   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 11:01 · PVG 19:01 · LAX 03:01 · JFK 06:01
    ♥ Do have faith in what you're doing.