我认为useEffectHook 在每次渲染后运行,如果提供了一个空的依赖数组:
useEffect(() => {
performSideEffect();
}, []);
Run Code Online (Sandbox Code Playgroud)
但是这和下面的有什么区别呢?
useEffect(() => {
performSideEffect();
});
Run Code Online (Sandbox Code Playgroud)
注意[]结尾的缺失。linter 插件不会发出警告。
我一直在学习 React,我读到从返回的函数useEffect是为了进行清理,而 React 在组件卸载时执行清理。
因此,我对其进行了一些试验,但在以下示例中发现,每次组件重新渲染时都会调用该函数,而不是仅在从 DOM 卸载时调用该函数,即每次组件重新渲染时都会调用该函数console.log("unmount");。
这是为什么?
function Something({ setShow }) {
const [array, setArray] = useState([]);
const myRef = useRef(null);
useEffect(() => {
const id = setInterval(() => {
setArray(array.concat("hello"));
}, 3000);
myRef.current = id;
return () => {
console.log("unmount");
clearInterval(myRef.current);
};
}, [array]);
const unmount = () => {
setShow(false);
};
return (
<div>
{array.map((item, index) => {
return (
<p key={index}>
{Array(index + 1)
.fill(item)
.join("")}
</p>
);
})}
<button onClick={() => …Run Code Online (Sandbox Code Playgroud) 这是一个从 Firebase 存储呈现数据并将其列出的组件。该函数要做的就是将从 firebase 存储中提取的视频设置为 useState。这样我就可以调用视频并映射到一个新组件中,该组件恰好是一个按钮列表。它工作得相对很好,问题是该组件渲染了两次,第一次它不保存状态中的视频,第二次它这样做。换句话说,该组件不会等待视频保存在状态中,而只是渲染自身,导致带有视频标题的按钮列表不显示。
// ReactJS
import { useState, useEffect } from "react";
// NextJS
import { useRouter } from "next/router";
// Seo
import Seo from "../../../components/Seo";
// Hooks
import { withProtected } from "../../../hook/route";
// Components
import DashboardLayout from "../../../layouts/Dashboard";
// Firebase
import { getDownloadURL, getMetadata, listAll, ref } from "firebase/storage";
import { storage } from "../../../config/firebase";
// Utils
import capitalize from "../../../utils/capitalize";
import { PlayIcon } from "@heroicons/react/outline";
function Video() {
// States
const [videos, setVideos] …Run Code Online (Sandbox Code Playgroud) 在 useEffect 函数中,如果我只提到 getResults 函数变量,应用程序不会崩溃。但是当我在下面的代码中调用它时,我收到这些错误:
react-dom.development.js:21857 Uncaught TypeError: destroy 不是函数
和
考虑向树添加错误边界以自定义错误处理行为。
function App() {
const [foods, setFoods] = useState([]);
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => getResponse());
const getResponse = async () => {
const response = await fetch(sampleRequest);
const data = await response.json();
setFoods(data.hits);
};
let query = "Tomato";
let sampleRequest = `https://api.edamam.com/search?q=${query}&app_id=${"1811484f"}&app_key=${"9cac93361efc99e2ebfbb8a453882af8"}`;
return (
<div className="App">
<div className="main">
<div className="navbars">
{" "}
<Navbars></Navbars>
</div>
<div className="listings">
<Listing></Listing>
<Listing></Listing>
<Listing></Listing>
<Listing></Listing>
<Listing></Listing>
<Listing></Listing>
<Listing></Listing>
<Listing></Listing>
<Listing></Listing>
<Listing></Listing>
</div> …Run Code Online (Sandbox Code Playgroud) How are you. This is scenario of this issue. Let's say there are 2 screens to make it simple.
navigate back to A screen from B. at this time, useEffect is not called.
function CompanyComponent(props) {
const [roleID, setRoleID] = useState(props.user.SELECTED_ROLE.id)
useEffect(()=>{
// this called only once when A screen(this component) loaded,
// but when comeback to this screen, it doesn't called
setRoleID(props.user.SELECTED_ROLE.id)
}, [props.user]) …Run Code Online (Sandbox Code Playgroud)我有一个道具从父组件传递到子组件,该组件根据用户的输入而变化。
当子组件渲染之前该 prop 发生变化时,我想在子组件中触发数据获取。我该怎么做?
我通过使用尝试了以下方式useEffects(()=>{},[props.a, props.b]),但总是在渲染后调用。请帮忙!
import React, { useEffect, useState } from "react";
import "./styles.css";
export default function parentComponent() {
const [inputs, setInputs] = useState({ a: "", b: "" });
return (
<>
<input
value={inputs.a}
onChange={(event) => {
const value = event.target.value;
setInputs((prevState) => {
return { ...prevState, a: value };
});
}}
/>
<input
value={inputs.b}
onChange={(event) => {
const value = event.target.value;
setInputs((prevState) => {
return { ...prevState, b: value };
});
}}
/>
<ChildComponent a={inputs.a} …Run Code Online (Sandbox Code Playgroud) 在 React 文档的这个页面上:
https://reactjs.org/docs/faq-ajax.html
代码注释说...
注意:在这里处理错误而不是 catch() 块很重要,这样我们就不会吞下来自组件中实际错误的异常。
...关于在第二个参数.then之后处理错误fetch。文档中的完整片段是:
useEffect(() => {
fetch("https://api.example.com/items")
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result);
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
setIsLoaded(true);
setError(error);
}
)
}, [])
Run Code Online (Sandbox Code Playgroud)
它没有详细说明这个建议,我已经看到了许多使用 React 代码catch处理 API 调用错误的例子。我试过谷歌搜索,但找不到任何说明。
有人可以更详细地解释一下为什么我不应该catch用来处理fetch在useEffect钩子中进行API 调用时出现的错误吗?
还是在某些情况下可以这样做,而在其他情况下则不然?
“在组件中吞下异常 [...]”是什么意思? …
我正在使用 Effect 钩子从服务器获取数据,并将这些数据传递到反应表,在那里我使用相同的 api 调用从服务器加载下一组数据。当应用程序加载时,我收到如下警告
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
Run Code Online (Sandbox Code Playgroud)
效果挂钩:
useEffect(() => {
setPageLoading(true);
props
.dispatch(fetchCourses())
.then(() => {
setPageLoading(false);
})
.catch((error: string) => {
toast.error(error);
setPageLoading(false);
});
}, []);
Run Code Online (Sandbox Code Playgroud)
反应表页面:
<ReactTable
className="-striped -highlight"
columns={columns}
data={coursesData}
defaultPage={currentPage}
defaultPageSize={courses.perPage}
loading={isLoading}
manual={true}
onFetchData={setFilter}
/>
Run Code Online (Sandbox Code Playgroud)
设置过滤功能:
const setFilter = (pagination: …Run Code Online (Sandbox Code Playgroud) 我现在正在用 React 构建一个旋转木马。要滚动到我使用的单个幻灯片,document.querySelector如下所示:
useEffect(() => {
document.querySelector(`#slide-${activeSlide}`).scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest'
});
}, [activeSlide]);
Run Code Online (Sandbox Code Playgroud)
这是不好的做法吗?毕竟,我在这里直接访问 DOM?这样做的 React 方式是什么?
编辑:完整return方法
return (
<>
<button onClick={() => setActiveSlide(moveLeft)}>PREV</button>
<Wrapper id="test">
{children.map((child, i) => {
return (
<Slide id={`slide-${i}`} key={`slide-${i}`}>
{child}
</Slide>
);
})}
</Wrapper>
<button onClick={() => setActiveSlide(moveRight)}>NEXT</button>
</>
);
Run Code Online (Sandbox Code Playgroud) 我的应用程序工作正常,然后我将其更新为 React 18,现在,当我从一条路线导航到另一条路线时(如果当前路线使用 useEffect 在加载时调用某些 API),它会抛出“destroy is not a function”。我在这方面搜索过互联网,但每个问题都与此问题无关。也许反应 18 是新的,这就是为什么我找不到解决方案。尽管当我重新加载同一页面时,它加载得很好。就在我导航时应用程序崩溃了。如果我评论 useEffect 一切正常
这是我的 useEffect 代码
//on mount useEffect
useEffect(async () => {
getCases()
}, []);
//api calls functions ====>
//get cases function
const getCases = async () => {
const response = await Get(CASES.get, token);
setLoading(false);
if (!response.error) {
const { data } = response;
setCases(data);
console.log("fetched=======>", response);
} else {
setError(response.error);
console.log("error====>", response);
}
};
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误
Uncaught TypeError: destroy is not a function
at safelyCallDestroy (react-dom.development.js:22768:1)
at …Run Code Online (Sandbox Code Playgroud) reactjs ×10
use-effect ×10
react-hooks ×5
javascript ×4
fetch ×1
frontend ×1
next.js ×1
react-native ×1
react-table ×1
ref ×1
use-state ×1