首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >反应: useState还是useRef?

反应: useState还是useRef?
EN

Stack Overflow用户
提问于 2019-06-05 07:23:54
回答 9查看 51.3K关注 0票数 129

我在“useState()”网站上读到了React useState()useRef()的内容,我对一些似乎同时有useRef和useState解决方案的用例感到困惑,我不知道哪种方法是正确的。

来自“钩子常见问题”的关于useRef()

“useRef() Hook不仅适用于DOM参考文献,”ref“对象是一个通用容器,其当前属性是可变的,可以保存任何值,类似于类上的实例属性。”

使用useRef()

代码语言:javascript
运行
复制
function Timer() {
  const intervalRef = useRef();

  useEffect(() => {
    const id = setInterval(() => {
      // ...
    });
    intervalRef.current = id;
    return () => {
      clearInterval(intervalRef.current);
    };
  });

  // ...
}

使用useState()

代码语言:javascript
运行
复制
function Timer() {
  const [intervalId, setIntervalId] = useState(null);

  useEffect(() => {
    const id = setInterval(() => {
      // ...
    });
    setIntervalId(id);
    return () => {
      clearInterval(intervalId);
    };
  });

  // ...
}

这两个例子都有相同的结果,但是哪一个更好--为什么呢?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2019-06-05 07:36:29

两者的主要区别是:

useState会导致重呈现,而useRef不会.

它们之间的共同之处是,useStateuseRef都可以在重新呈现后记住它们的数据。因此,如果变量决定视图层呈现,则使用useState。否则使用useRef

我建议阅读这个文章

票数 234
EN

Stack Overflow用户

发布于 2021-07-05 17:02:33

当您希望跟踪值更改时,useRef非常有用,但不希望通过它触发重呈现或useEffect

大多数用例都是当您有一个依赖于值的函数时,但是这个值需要由函数结果本身来更新。

例如,让我们假设您想要分页一些API结果:

代码语言:javascript
运行
复制
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在反应中的作用。例如,如果要在加载组件时获取行,则需要执行如下操作:

代码语言:javascript
运行
复制
useEffect(() => {
  fetchData();
}, [fetchData]);

这是一个错误,因为我们使用状态并在相同的函数中更新它。

我们希望跟踪currentPage,但不希望通过更改触发useCallbackuseEffect

我们可以用useRef轻松地解决这个问题。

代码语言:javascript
运行
复制
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]);

我们可以借助currentPageuseCallback deps数组中删除useRef依赖项,这样我们的组件就可以从无限循环中保存下来。

票数 12
EN

Stack Overflow用户

发布于 2020-11-15 21:38:09

基本上,在那些情况下,我们使用UseState,在这种情况下,状态值应该通过重新呈现来更新。

当您希望您的信息在组件的生存期内保持不变时,您将使用UseRef,因为它不是用于重呈现的工作。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56455887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档