Hai*_*763 11 reactjs react-hooks
我读约阵营useState(),并useRef()在“ 鱼钩常见问题解答 ”,我糊涂了关于一些使用案例,似乎有useRef和useState解决方案的同时,我不知道哪条路是正确的方式。
从关于useRef()的“挂钩常见问题”中:
“ useRef()钩不仅用于DOM引用。“ ref”对象是通用容器,其当前属性是可变的,并且可以保存任何值,类似于类的实例属性。”
使用useRef():
function Timer() {
const intervalRef = useRef();
useEffect(() => {
const id = setInterval(() => {
// ...
});
intervalRef.current = id;
return () => {
clearInterval(intervalRef.current);
};
});
// ...
}
Run Code Online (Sandbox Code Playgroud)
使用useState():
function Timer() {
const [intervalId, setIntervalId] = useState(null);
useEffect(() => {
const id = setInterval(() => {
// ...
});
setIntervalId(id);
return () => {
clearInterval(intervalId);
};
});
// ...
}
Run Code Online (Sandbox Code Playgroud)
这两个示例将具有相同的结果,但是哪个示例更好-为什么?
gli*_*a93 14
useRef当您想要跟踪值更改但不想触发重新渲染或useEffect通过它触发重新渲染时非常有用。
大多数用例是当您有一个依赖于值的函数,但该值需要由函数结果本身更新时。
例如,假设您想要对某些 API 结果进行分页:
const [filter, setFilter] = useState({});
const [rows, setRows] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const fetchData = useCallback(async () => {
const nextPage = currentPage + 1;
const response = await fetchApi({...filter, page: nextPage});
setRows(response.data);
if (response.data.length) {
setCurrentPage(nextPage);
}
}, [filter, currentPage]);
Run Code Online (Sandbox Code Playgroud)
fetchData正在使用currentPage状态,但响应成功后需要更新currentPage。这是不可避免的过程,但很容易导致Maximum update depth exceeded errorReact中的无限循环。例如,如果您想在加载组件时获取行,您需要执行以下操作:
useEffect(() => {
fetchData();
}, [fetchData]);
Run Code Online (Sandbox Code Playgroud)
这是有问题的,因为我们使用状态并在同一函数中更新它。
我们想要跟踪currentPage但不想useCallback通过useEffect它的改变来触发。
我们可以通过以下方法轻松解决这个问题useRef:
const currentPageRef = useRef(0);
const fetchData = useCallback(async () => {
const nextPage = currentPageRef.current + 1;
const response = await fetchApi({...filter, page: nextPage});
setRows(response.data);
if (response.data.length) {
currentPageRef.current = nextPage;
}
}, [filter]);
Run Code Online (Sandbox Code Playgroud)
我们可以在 的帮助下currentPage从 deps 数组中删除依赖关系,这样我们的组件就可以避免无限循环。useCallbackuseRef
useState 和 useRef 之间的主要区别是 -
引用的值在组件重新渲染之间保持不变(保持不变),
使用 更新引用useRef不会触发组件重新渲染。但是,更新状态 c会导致组件重新渲染
引用更新是同步的,更新后的引用值立即可用,但状态更新是异步的——值在重新渲染后更新。
使用代码查看:
import { useState } from 'react';
function LogButtonClicks() {
const [count, setCount] = useState(0);
const handle = () => {
const updatedCount = count + 1;
console.log(`Clicked ${updatedCount} times`);
setCount(updatedCount);
};
console.log('I rendered!');
return <button onClick={handle}>Click me</button>;
}
Run Code Online (Sandbox Code Playgroud)
每次单击该按钮时,都会显示我渲染了!
然而,随着useRef
import { useRef } from 'react';
function LogButtonClicks() {
const countRef = useRef(0);
const handle = () => {
countRef.current++;
console.log(`Clicked ${countRef.current} times`);
};
console.log('I rendered!');
return <button onClick={handle}>Click me</button>;
}
Run Code Online (Sandbox Code Playgroud)
我的渲染将仅被控制台记录一次。
| 归档时间: |
|
| 查看次数: |
1944 次 |
| 最近记录: |