useState挂钩不起作用或不会触发

时间:2020-03-04 09:30:15

标签: javascript reactjs react-hooks

这是我的post组件working.req函数在安装时起作用,并且在onScroll函数触发但钩子不起作用或从未触发时。始终显示第1页的值


const PostsComponent = () => {
  const [totalPage, setTotalPage] = useState(1)
  const [loading, setLoading] = useState(false)
  const [tags, setTags] = useState([]);
  const [haveMore, setHaveMore] = useState(null)
  const { items } = useSelector(state => ({
    items: state.posts.items
  }));
  const [page, setPage] = useState(1)
  const dispatch = useDispatch();

  const req = () => {
    if (page <= totalPage) {
      setLoading(true)
      getPosts(page).then(res => {
        res.posts.map(item => dispatch(getterPosts(item)));
        res.posts.length > 0 ? setHaveMore(true) : setHaveMore(false)
        setTotalPage(Math.ceil(res.total / 6));
      }).finally(f => setLoading(false), setPage(page + 1));
    }
  };

  const onScroll = event => {
    const { scrollHeight, scrollTop, offsetHeight } = event.srcElement;
    if (scrollTop + offsetHeight === scrollHeight) {
      req();
    }
  };

};


服务中的getPosts函数

export const getPosts = page => {
  return new Promise((resolve, reject) => {
    axios
      .get(`${BASE_URL}/api/posts?page=${page}`)
      .then(res => resolve(res.data))
      .catch(err => reject(err.response.data.message));
  });
};

1 个答案:

答案 0 :(得分:0)

有两个问题:

  1. 您的page变量在使用时可能已过时,因为您的组件可能在finally回调之前已重新渲染。

  2. 此行没有执行您可能希望执行的操作:

    }).finally(f => setLoading(false), setPage(page + 1))
    

    该操作是调用 setPage(page + 1),然后调用finally并传入函数f => setLoading(false)和值undefined(致电setPage)。这是不使用逗号运算符来使用箭头函数的简洁形式的众多原因之一。

您可以通过以下方式修复它们

  1. 使用setPage的回调版本,该版本始终接收状态项的当前值
  2. 使用箭头函数的函数主体形式,包含要在finally处理程序中进行的两次调用

赞:

}).finally(f => {
    setLoading(false);
    setPage(p => p + 1);
});

我建议阅读Dan Abramov的this article。表面上讲,它是关于useEffect的,但是在此过程中,他很好地解释了过时的状态变量之类的东西……