Эффект использования реакции, вызывающий бесконечную повторную визуализацию, несмотря на передачу аргумента в массив зависимостей

#reactjs #react-hooks #render

#reactjs #реагирующие крючки #визуализация

Вопрос:

У ‘myPosts’ есть объект с несколькими записями внутри него.. Я хотел, чтобы профиль пользователя сразу показывал сообщение после его загрузки, поэтому я передал ‘myposts’ в массив зависимостей.

Но проблема в том, что компонент повторяет рендеринг бесконечно. Как я могу сделать так, чтобы он повторно отображался один раз, только при загрузке нового сообщения? Я не могу понять, почему передача ‘myposts’ в массив вызывает бесконечный рендеринг, а не только один раз.

   const [myposts, setPosts] = useState([]);
  useEffect(() => {
  fetch('/mypost', {
    headers: {
     cookie: 'access_key',
    },
   })
     .then((res) => res.json())
     .then((data) => {
     // console.log(data);
     setPosts(data.myposts);
  });
 }, [myposts]);
 

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

1. React используется Object.is() для определения, изменилась ли зависимость и Object.is({}, {}) => false . Даже если из вашего запроса возвращаются одни и те же сообщения, тот факт, что вы извлекаете новый объект, означает, что ваша useEffect зависимость изменилась.

Ответ №1:

При разрешении выборки он изменяет myposts, что запускает выборку, поскольку он указан как зависимость от useEffect, которая изменяет myposts, и так продолжается…

Кажется, что myposts зависит от результата выборки, а не наоборот. Поэтому я бы предложил удалить myposts из списка зависимостей.

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

1. Теперь я понимаю, почему это вызывает бесконечный цикл .. но есть ли какой-либо другой способ повторного рендеринга компонента при загрузке нового сообщения? Хотелось бы узнать подходы, пожалуйста.

2. Поскольку myposts является частью состояния компонента, всякий раз, когда myposts изменяется, компонент повторно отображается автоматически.

Ответ №2:

Перехват useEffect вызывается при myposts обновлении. В финале .then вашей выборки вы обновляете его с помощью setPosts . Лучший способ исправить это — сделать массив зависимостей пустым массивом.
Но это не решит проблему обновления сообщений с сервера, но это также можно сделать с помощью периодической функции setInterval . Это приведет к чему-то вроде приведенного ниже кода.

 const [myposts, setPosts] = useState([]);

const update = fetch('/mypost', {
  headers: {
    cookie: 'access_key',
  },
})
.then((res) => res.json())
.then((data) => {
  // console.log(data);
  setPosts(data.myposts);
});

useEffect(() => {
  update()
  const interval = setInterval(update, 30000)
  return () => clearInterval(interval)
}, []);
 

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

1. Спасибо за объяснение! Я попробую ваше решение, но просто хотел знать .. есть ли у них какие-либо другие альтернативы?

2. Есть несколько альтернатив для получения обновлений с сервера. Описанный выше подход основан на опросе (позволяя клиенту проверять время от времени), но вы также можете просмотреть отправленные сервером события или веб- сокеты . Существуют некоторые библиотеки, которые упрощают использование этих технологий, но по своей сути все они используют один (или несколько) из этих трех методов

3. Большое спасибо! проверит их 🙂