очень странная вещь с функцией прокрутки в useEffect react

#javascript #reactjs

#javascript #reactjs

Вопрос:

у меня есть div, который содержит сообщения чата, и я хочу, чтобы он прокручивался до последнего сообщения сразу после рендеринга. итак, когда я использовал функцию прокрутки для этого div в useEffect, она не работала, но когда я запускал ее внутри setTimeout, она работала

   useEffect(()=>{
            getConversation()//fetch the conversation
            setTimeout(() => {
                holder.current.scroll(0, holder.current.scrollHeight)          
            console.log('=====================>',holder.current.scrollHeight)

            }, 400);
    },[getConversation])  

и что действительно странно, если я установлю время на 200 мс вместо 400 мс, оно не будет работать

Комментарии:

1. почему вы используете setTimeout

2. Я думаю, что ваш метод getConverstion() требует много времени для выполнения, поэтому, когда вы добавляете setTimeout(), ваша предыдущая функция получает время для выполнения и, следовательно, дает желаемый результат.

3. — я использую settimeout, потому что вместо этого он не будет работать

4. итак, что, по-твоему, я должен делать, Рохит

5. setTimeout это почти всегда запах кода. Вам нужно запустить вашу функцию как обратный вызов. Попытка определить время загрузки вашего соединения не будет переведена на более медленные соединения других пользователей.

Ответ №1:

Выборка и прокрутка должны быть разделены.

Выборка происходит при первой загрузке компонента.

Прокрутка должна происходить при загрузке содержимого, а страница еще не прокручена до верха, поэтому прокрутка должна зависеть только от этих двух критериев, например:

   useEffect(()=>{
      getConversation() // <--- updates state 'conversations'
  },[ getConversation ]);

  useEffect(()=>{
      if( needsToScroll ){  // <-- check somehow if already top
          holder.current.scroll(...)
      }
  }, [ conversation ]);
 

needsToScroll Условие может быть опущено, тогда страница пытается прокручиваться при каждом изменении conversation , что, вероятно, не видно, не часто и нормально.

С другой стороны, может потребоваться опустить всю зависимость ( [ conversation ] ), если вам нужно проверить, holder.current доступна ли она (при каждом рендеринге). Затем needsToScroll можно проверить оба holder.current и conversation .