新手问题请教 useEffect

154 天前
 yagamil
代码是 React 学习手册里面的
```javascript
import { useState, useEffect } from "react";

export default function GitHubUser({ login }) {
return (
<Fetch
uri={`https://api.github.com/users/${login}`}
renderSucess={UserDetails}
/>
);
}

function UserDetails({ data }) {
return (
<div className="githubuser">
<img src={data.avatar_url} alt={data.login} style={{ width: 200 }} />
<div>
<h1>{data.login}</h1>
<p>
{data.name} - {data.location}
</p>
</div>
</div>
);
}

function Fetch({
uri,
renderSucess,
loadingFallback = <p>loading....</p>,
renderError = (error) => <pre>{JSON.stringify(error)}</pre>,
}) {
const { loading, data, err } = useFetch(uri);
if (loading) return loadingFallback;
if (err) return renderError(err);
if (data) return renderSucess({ data });
}

//let uri = `https://api.github.com/users/${login}`

function useFetch(uri) {
const [data, setData] = useState();
const [error, setError] = useState();
const [loading, setLoading] = useState(true);

useEffect(() => {
console.log(`enter into efffect ${uri} ==== `);
if (!uri) return;

fetch(uri)
.then((res) => res.json())
.then(setData)
.then(() => setLoading(false))
.catch((err) => setError(err));
}, []);

return { loading, data, error };
}
```

在浏览器的控制台里面,useEffect 执行了 2 次,
也就是打印了 2 次
enter into efffect HELLO ====
enter into efffect HELLO ====

无论 useEffect 里监控的值[] 是哪个,都会执行 2 次。
```
useEffect(() => {
console.log(`enter into efffect ${uri} ==== `);
if (!uri) return;

fetch(uri)
.then((res) => res.json())
.then(setData)
.then(() => setLoading(false))
.catch((err) => setError(err));
}, []);
```

书本数如果数组中括号里面没有变量,那么只会低第一次渲染的时候执行。 不知道为什么现在会被执行 2 次的?
1136 次点击
所在节点    React
6 条回复
yena
154 天前
useeffect 默认执行两次
whj768702
154 天前
是严格模式,看看入口文件中是不是有<StrictMode>标签包裹,在开发环境,严格模式下会执行两次。可以参考下文档。https://react.dev/reference/react/StrictMode
daleqq
154 天前
Development 模式下默认执行两次 mount 提醒你有没有合理的 cleanup.

"To help you spot them quickly, in development React remounts every component once immediately after its initial mount."
potatowish
154 天前
初学 React 时也遇到过,开发环境下默认是 StrictMode
realJamespond
154 天前
```
export const useMount = (fn: React.EffectCallback) => {
const isMounted = useRef(false)
useEffect(() => {
if (!isMounted.current) {
fn()
isMounted.current = true
}
}, [])
}
```
这样就能只执行一次了
nodejsexpress
153 天前
好的,看来还是我太菜了。谢谢楼上的各位大佬!

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

https://www.v2ex.com/t/998520

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

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

© 2021 V2EX