我知道 ref 是一个可变容器,因此不应在useEffect的依赖项中列出它,但它ref.current可能是一个不断变化的值。
当 ref 用于存储像 DOM 元素时<div ref={ref}>,并且当我开发依赖于该元素的自定义钩子时,假设ref.current如果组件有条件地返回,则可以随着时间的推移而改变,例如:
const Foo = ({inline}) => {
const ref = useRef(null);
return inline ? <span ref={ref} /> : <div ref={ref} />;
};
Run Code Online (Sandbox Code Playgroud)
我的自定义效果接收ref对象并ref.current用作依赖项是否安全?
const Foo = ({inline}) => {
const ref = useRef(null);
return inline ? <span ref={ref} /> : <div ref={ref} />;
};
Run Code Online (Sandbox Code Playgroud)
我读过这个评论说 ref 应该用于useEffect,但我无法弄清楚任何情况下ref.current改变但效果不会触发。
正如那个问题所建议的那样,我应该使用回调引用,但是引用作为参数对于集成多个钩子非常友好:
const useFoo = ref => { …Run Code Online (Sandbox Code Playgroud) 我目前正在查看 useEffect 的 react 文档示例
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我们可以轻松地为按钮创建一个 handleClick 函数。我们不必使用 useEffect
const handleButtonClick = () =>{
setCount(count+1)
document.title = `You clicked ${count …Run Code Online (Sandbox Code Playgroud) 我只希望 useEffect 在我的依赖项列表更改时运行,它也在每次挂载组件时运行,有什么方法可以不在挂载时触发?
如果某些值在重新渲染之间没有改变,你可以告诉 React 跳过应用效果。
我最初认为这意味着它不应该在随后的装载上重新渲染,但这个问题澄清了这一点。
我在主“页面”(反应路由器)中显示记录列表,用户可以选择单个记录并转到详细信息页面,然后返回到主页面-因此主列表组件完全卸载/安装在那个场景中。每次加载“母版页”时,我都会看到正在获取的数据,我只希望在依赖项之一发生更改时发生这种情况;这些依赖项和数据本身存储在 Redux 中,因此它们是全局的。
是否可以使 useEffect 或其他钩子仅在依赖项更改时触发?
const {page, pageSize, search, sorts} = useSelector(getFilters);
const data = useSelector(getData);
useEffect(() => {
console.log("fetching");
dispatch(fetchData(page, pageSize, search, sorts));
}, [page, pageSize, search, sorts]);
Run Code Online (Sandbox Code Playgroud) 我有一个反应功能组件,我想在每个渲染中运行一些代码。你知道useEffect没有依赖数组的钩子每次在渲染时都会运行。
继承人的代码
function Component({a, b}){
useEffect(()=>{
console.log('component rerenderd')
// some code here
})
return(
<div>
Some content
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
另一方面没有 useEffect 做同样的事情
function Component2({a, b}){
console.log('component rerenderd')
// some code here
return(
<div>
Some content
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
我的问题是它们之间有什么区别?
function Example() {
const [count, setCount] = useState(0);
//THE SUBJECT OF MY QUESTION:
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是为什么不使用 useEffect 更改 document.title 或任何其他 DOM,如下所示:
function Example() {
const [count, setCount] = useState(0);
//THE SUBJECT OF MY QUESTION:
document.title = `You clicked ${count} times`;
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() …Run Code Online (Sandbox Code Playgroud) 如何在每个“ useEffect”中使用变量的更新值(在组件范围内声明)?
import React, { useState, useEffect } from 'react';
export default function Count() {
const [count, setCount] = useState(0);
let a = 10;
useEffect(() => {
console.log('after 1st render', a);
a++;
console.log(a);
return () => { console.log('cleanup - on unmount.') }
}, [a]);
useEffect(() => {
console.log('only when count changes', a);
a++;
return () => { console.log('count cleanup', a) }
}, [count, a]);
return <div>
<p>Count : {count}</p>
<button onClick={() => { console.log('at global', a); setCount(count + 1) }}>Click</button> …Run Code Online (Sandbox Code Playgroud) 我想澄清我对这里发生的事情的理解。任何改善我目前理解的细节将不胜感激。
function Timer() {
let [time, setTime] = useState(5);
useEffect(() => {
let timer = setInterval(() => {
setTime(time - 1);
}, 1000)
return () => clearInterval(timer);
}, );
return <div>{time}</div>
}
export default Timer
Run Code Online (Sandbox Code Playgroud)
https://codesandbox.io/s/cranky-chaplygin-g1r0p
time正在初始化为5.useEffect已读。它的回调必须准备好稍后触发。div呈现。useEffect的回调被执行。setInterval的回调准备好触发。当然useEffect'sreturn语句不会在这里触发,因为如果它触发它会取消计时器(并且计时器确实有效)。setInterval的回调触发将time( 到 4)的状态更改。time,一个新变量,被初始化为新的时间状态。useEffect读取一个新的,它的回调准备稍后触发。(发生这种情况是因为没有 的第二个参数useEffect())。return语句。这有效地重新渲染了div.useEffect的return语句会执行(这会禁用 …我正在尝试更新(增量)每个 setInterval 函数的 React 状态(计数器),但它无法按预期工作。在前 5 秒左右,计数以一致的增量呈现,但之后它会随机增加并且不会停止。
export default function App() {
const [count, setCount] = useState(0);
setInterval(() => setCount((oldCount) => oldCount + 1), 1000);
return (<>
<div>{count}</div>
</>);
};
Run Code Online (Sandbox Code Playgroud)
我怎样才能实现这一点以及在小于一秒(100 或 10 毫秒)的时间间隔内实现相同的效果?
我有一个简单的 React 组件,每次单击按钮时我都会设置相同的值:
import React, { useState } from 'react';
import './style.css';
let data = { title: 'ABC' };
export default function App() {
const [foo, setFoo] = useState();
console.log('Rendered');
return (
<div>
<button onClick={() => setFoo(data)}>Set Data</button>
<h1>Data: {JSON.stringify(foo)}</h1>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
但渲染有点奇怪,因为在第二个按钮上单击 React 渲染组件,但我设置了相同的值。尽管我设置了相同的值,为什么 React 会重新渲染组件?
我已阅读了《使用效果的完全指南-过度反应应对潮流》。
该示例表明,如果我们想获取最新的count,我们可以useRef用来保存可变变量,并在异步函数laster中获取它:
function Example() {
const [count, setCount] = useState(0);
const latestCount = useRef(count);
useEffect(() => {
// Set the mutable latest value
latestCount.current = count;
setTimeout(() => {
// Read the mutable latest value
console.log(`You clicked ${latestCount.current} times`);
}, 3000);
});
// ...
}
Run Code Online (Sandbox Code Playgroud)
但是,我可以通过在组件函数外部创建一个变量来执行相同的操作,例如:
import React, { useState, useEffect, useRef } from 'react';
// defined a variable outside function component
let countCache = 0;
function Counter() {
const [count, setCount] = useState(0); …Run Code Online (Sandbox Code Playgroud)