yazoox
V2EX  ›  React

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

  •  
  •   yazoox · Nov 5, 2020 · 4398 views
    This topic created in 2195 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
    star7th
    Nov 5, 2020
    1
    提供一下原教程链接看看。谁知道这是源码还是经过你加工出来的问题代码
    syfless
    syfless
    Nov 5, 2020
    2
    这段 useEffect 里的代码意义不明,本来就是 name 变化之后执行 useEffect 里的副作用,但 useEffect 又放了无条件改变 name 的代码,这就死循环了,不过好像 useEffect 里面会自动检测会不会死循环,顶多是执行几十次就停了
    codesandbox.io 可以
    shenyu1996
    shenyu1996
    Nov 5, 2020
    3
    [name] => []
    CptDoraemon
    CptDoraemon
    Nov 5, 2020 via Android
    4
    setState's identity is guaranteed to be stable over components's life cycle. 文档里说的
    easonHHH
    easonHHH
    Nov 5, 2020
    5
    当 name 发生变化后,然后就从 api 获取一个 new name 然后赋值到 name ?
    anjianshi
    anjianshi
    Nov 5, 2020
    6
    按上面的代码,useEffect 确实没啥用,而且会死循环
    u6pM63mMZ34z32cE
    u6pM63mMZ34z32cE
    Nov 5, 2020
    7
    <button onclick={clickme()} >click me</button>
    这行代码没看懂 clickme()不是 undefined 吗
    dartabe
    dartabe
    Nov 5, 2020
    8
    建议多看看好点的教程 有点不知所云

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

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