我在“useState()”网站上读到了React useState()和useRef()的内容,我对一些似乎同时有useRef和useState解决方案的用例感到困惑,我不知道哪种方法是正确的。
来自“钩子常见问题”的关于useRef()
“useRef() Hook不仅适用于DOM参考文献,”ref“对象是一个通用容器,其当前属性是可变的,可以保存任何值,类似于类上的实例属性。”
使用useRef()
function Timer() {
const intervalRef = useRef();
useEffect(() => {
const id = setInterval(() => {
// ...
});
intervalRef.current = id;
return () => {
clearInterval(intervalRef.current);
};
});
// ...
}使用useState()
function Timer() {
const [intervalId, setIntervalId] = useState(null);
useEffect(() => {
const id = setInterval(() => {
// ...
});
setIntervalId(id);
return () => {
clearInterval(intervalId);
};
});
// ...
}这两个例子都有相同的结果,但是哪一个更好--为什么呢?
发布于 2019-06-05 07:36:29
两者的主要区别是:
useState会导致重呈现,而useRef不会.
它们之间的共同之处是,useState和useRef都可以在重新呈现后记住它们的数据。因此,如果变量决定视图层呈现,则使用useState。否则使用useRef
我建议阅读这个文章。
发布于 2021-07-05 17:02:33
当您希望跟踪值更改时,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]);fetchData正在使用currentPage状态,但它需要在成功响应后更新currentPage。这是不可避免的过程,但它容易导致无限循环,也就是Maximum update depth exceeded error在反应中的作用。例如,如果要在加载组件时获取行,则需要执行如下操作:
useEffect(() => {
fetchData();
}, [fetchData]);这是一个错误,因为我们使用状态并在相同的函数中更新它。
我们希望跟踪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]);我们可以借助currentPage从useCallback deps数组中删除useRef依赖项,这样我们的组件就可以从无限循环中保存下来。
发布于 2020-11-15 21:38:09
基本上,在那些情况下,我们使用UseState,在这种情况下,状态值应该通过重新呈现来更新。
当您希望您的信息在组件的生存期内保持不变时,您将使用UseRef,因为它不是用于重呈现的工作。
https://stackoverflow.com/questions/56455887
复制相似问题