如何避免useEffect 执行两次

发布于 2022-09-13 01:26:10 字数 550 浏览 16 评论 0

  const {keyword} = query
  const {page, pageSize} = table.pagination 

  useEffect(() => {
    setTable(prevState => ({
      ...prevState,
      pagination: {...prevState.pagination, page: 1}
    }))
  }, [keyword])

  useEffect(() => {
    fetchList()
  }, [page, pageSize, keyword])

表格改变查询条件时,需要将表格分页重置为第一页。但是fetchList会执行两次。
需要怎么做,才能让fetchList只执行一次

demo链接:https://codesandbox.io/s/obje...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

渔村楼浪 2022-09-20 01:26:10

正确做法是不应该把重置为第一页这个事情写成一个effect…
如果你还有别的东西要重置(比如重置排序参数、重置分页大小),每个重置都单独写一个effect,那你可能不止重复渲染一次,而是重复渲染n次;

setState的时候自己手动去干这个事情而不是用effect去干;嫌麻烦可以把这个手动干的过程给封起来

/** @param init @param {(preState, nextState) => mergedSatte} onUpdate */
export function useStateWithCycle(init, onUpdate) {
    const [state, setState] = useState(init)
    function setStateWithCycle (nextState) {
        if (typeof nextState === 'function') {
            setState(pre => onUpdate( pre, nextState(pre) ))    
        } else {
            setState(pre => onUpdate( pre, nextState ))    
        }
    }

    return [state, setStateWithCycle]
}
半仙 2022-09-20 01:26:10

使用debounce来延迟触发请求应该就行了,也能避免你快速切换页数,修改keyword,简单写个demo

https://codesandbox.io/embed/...

不醒的梦 2022-09-20 01:26:10

首先,如果有合并机制,useEffect 的多个依赖项就没有意义,根据你的代码,keyword 切换仅仅对引起的 page 重置,看下面代码:

  const {keyword} = query
  const {page, pageSize} = table.pagination 

  useEffect(() => {
    if(!keyword) {
        return
    }
    if(page === 1) {
        fetchList()
    } else {
        setTable(prevState => ({
          ...prevState,
          pagination: {...prevState.pagination, page: 1}
        }))
    }
  }, [keyword])

  useEffect(() => {
    fetchList()
  }, [page, pageSize])

已经在你的 demo 上测试了,可以正常运行

没︽人懂的悲伤 2022-09-20 01:26:10

方案之一:

 // useEffect(() => {
  //   setPagination((prevState) => ({ ...prevState, page: 1 }));
  // }, [keyword]);

  function handleInputChange(e) {
    const keyword = e.target.value;
    setQuery((prevState) => ({ ...prevState, keyword }))
    setPagination((prevState) => ({ ...prevState, page: 1 }));
  }

参考解密React state hook

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文