перехватчики useState не работают или не срабатывают - PullRequest
1 голос
/ 04 марта 2020

Эта функция моего пост-компонента 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 голосов
/ 04 марта 2020

Есть две проблемы:

  1. Ваша переменная page может устареть к тому времени, когда вы ее используете, потому что ваш компонент может быть повторно отрендерен до finally callback.

  2. Эта строка не делает то, что вы, вероятно, хотите, чтобы она делала:

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

    То, что это делает, call setPage(page + 1), а затем вызвать finally, передав функцию f => setLoading(false) и значение undefined (результат вызова setPage). Это одна из многих причин не использовать оператор запятой для использования краткой формы функции стрелки.

Вы можете исправить их с помощью

  1. Использование версии обратного вызова setPage, которая всегда получает текущее значение элемента состояния
  2. Использование формы тела функции функции стрелки, содержащей два вызова, которые вы хотите сделать в обработчике finally

Вот так:

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

Рекомендую прочитать эту статью Дана Абрамова. Якобы, это примерно useEffect, но по пути он очень хорошо объясняет такие вещи, как устаревшие переменные состояния ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...