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

2020 年 11 月 5 日
 yazoox

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

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

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

文章就得去看这个大神
azcvcza
2020 年 11 月 6 日
你这和原先 componentWillRecieveProps 里把 拿来的 props 赋值给 state 引起无限循环差不多
jingcoco
2020 年 11 月 6 日
3 楼靠谱.....useEffect 的第二个参数

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://study.congcong.us/t/722045

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX