Задать вопрос
@Alex657913

Как получить актуальные данные в state при использовании server side event (в момент срабатывания события) в компоненте React?

Приветствую.
Есть проблема, не могу найти решения. Буду очень признателен за "наводку" или решение.
Итак, есть компонент содержащий коллекцию эл-тов (ul). Объекты для коллекции (li) хранятся в стейте dialogs.
В useEffect
1) вызывается loadRows(), который загрузит первые 50 объектов и
2)подписка на SSE, который нужен для получения новых объектов dialog c api.
Остальные объекты могут подгружатся на скроле в loadRows(), когда срабатывает событие при достижении границы прокрутки (infinity scroll). Реализацию loadRows() не привожу за ненадобностью.
Суть проблемы:
Допустим сначала загрузился компонент списка - в dialogs 50 эл-тов, затем мы подвигали скроллом - стейт dialogs стал содержать 300 эл-тов.
Теперь срабатывает events.onmessage (прилетел dialog с апи) и в функции которая обрабатывает событие (onmessage), мы обращаемся к стейту dialogs - в нем окажется не 300, а 50 эл-тов. Т.е. в стейте будут сообщения полученные только при инициализации. Пытался использовать редакс, та же фигня (или 0 или 50) . Я думаю, что при вызове createEvents() в useEffect events.onmessage замыкает текущий контекст. Вопрос как можно выйти из такого положение. Есть ли какое-то решение?
Собственно вопрос: Как получить актуальные данные в state при использовании server side event в момент срабатывания события?

Пример кода
export default function ConversationList() {

    let [dialogs, setDialogs] = useState([]);
    let [events, setEvents] = useState(null);

    useEffect( () => async() => {
        await loadRows();
        await createEvents();
    }, []);

    async function createEvents() {
        if (events) events.close();
        setEvents(events = new EventSource(apiHost + urlPaths.eventRegistration));

        events.onmessage = (ev) => {
            const parsedData = JSON.parse(ev.data);
            const id = parsedData?.dialog?._id.toString();
            setDialogs([parsedData?.dialog, ...dialogs?.filter((dialog) => dialog?._id.toString() !== id)]);           
        }
    }
}
  • Вопрос задан
  • 115 просмотров
Подписаться 1 Средний 7 комментариев
Решения вопроса 1
@gUWUis
добавь поверх кода функцию reboot.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы