• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Nie wyświetlanie się elementów tablicy Firebase

Object Storage Arubacloud
0 głosów
164 wizyt
pytanie zadane 28 maja 2020 w JavaScript przez poldeeek Mądrala (5,980 p.)

Napisałem aplikację, która pobiera z bazy danych informacje o wydarzeniu. W wydarzeniu znajduje się tablica referencji do użytkowników uczestniczących. Informacje o wydarzeniu przekazuje w propsach do innego komponentu. Mój problem polega na tym, że nie aplikacja nie chce wyświetlić tych użytkowników. Z tego co widzę po console logach i stanie komponentu wszystko działa. Jedna dziwna rzecz to tutaj :
 

        console.log(new_members)
        setMembers(new_members)
        console.log(members)

Pierwszy console.log(new_members) poprawnie wyświetla moją tablicę, jednak drugi wyświetla ją jako tablicę pustą.

 

    const [members, setMembers] = useState([])

    useEffect( () => {
        console.log("ha")
        getMembers();
    }, [props.event])

    const getMembers = async () => {
        let new_members = [];
        console.log(props.event)
         props.event &&  props.event.uczestnicy.map( async member => {
            member.get().then(doc => {
                let new_member;
                new_member = {
                    ...doc.data(),
                    id: doc.id
                }
                new_members.push(new_member)
            })
        })        
        console.log(new_members)
        setMembers(new_members)
        console.log(members)
    }

I kod wyświetlenia :
 

                {members && members.map(member => {
            console.log(member)
            return(
                <div key={member.id}>
                    {member.nick}
                </div>
            )
        })}

 

komentarz 28 maja 2020 przez ScriptyChris Mędrzec (190,190 p.)

Co napełnia tablicę members? Czy kod z drugiego bloczka coś wyświetla - masz tam sprawdzanie czy members jest truthy (jako nawet tablica - jest), ale skoro tablica jest pusta, to members.map się pewnie nie odpala? 

komentarz 28 maja 2020 przez poldeeek Mądrala (5,980 p.)

Nic się nie wyświetla przy funkcji .map(member => {...}). Co ciekawe mam guzik w innym komponencie, który dodaje lub usuwa z wydarzenia akutalnego użytkownika. Jeśli dodam się pierwszy raz - tablica ładnie się wyświetla nawet z dodanym właśnie użytkownikiem. Jeśli jednak opuszczę wydarzenie elementy znów się nie wyświetlają już w ogóle (nawet jeśli z powrotem się dodam). Jednak w konsoli mogę zobaczyć rezultat console.log(member), który znajduję się w tej funkcji .map().

Może będzie prościej jeśli dodam te dwa komponenty w całości :P - https://codesandbox.io/s/gracious-snow-1ypoe?file=/src/eventUsers.js

komentarz 28 maja 2020 przez ScriptyChris Mędrzec (190,190 p.)

Nic się nie wyświetla przy funkcji .map(member => {...})

+

Jednak w konsoli mogę zobaczyć rezultat console.log(member), który znajduję się w tej funkcji .map().

To kiedy w callbacku przekazanym do members.map coś się pokazuje?

Ponawiam pytanie - co napełnia tablicę members (po nazwie domyślam się, że funkcja setMembers, ale w jaki sposób to robi)?


Czy jeśli z tych trzech linijek:

console.log(new_members)
setMembers(new_members)
console.log(members)

w pierwszej zapiszesz console.log(JSON.parse(JSON.stringify(new_members))) , to co pokazuje konsola?

komentarz 28 maja 2020 przez poldeeek Mądrala (5,980 p.)

"To kiedy w callbacku przekazanym do members.map coś się pokazuje?" - Po jakichś zmianach w props.event. Wyświetla mi w konsoli tak jakby poprzedni stan tablicy members.

(mówię tylko o konsoli - na ekranie dalej nic)

A funckja setMembers jest elementem hook'a useState z React.js. Wygląda tak :
 

const [members, setMembers] = useState([])

, gdzie members jest zmienną, a setMembers funkcją w której przekazujemy nową zawartość, która ma się znaleźć w memberes. useState([]) - w nawiasie jest stan początkowy zmiennej members. 

Co do ostatniego pytania :
 

        console.log("JSON.parse(JSON.stringify(new_members))",JSON.parse(JSON.stringify(new_members)))
console.log("new_members",new_members)

Wynik w consoli :

Jeśli to pomoże to wrzuciłem pełny kod tych 2 komponentów :

https://codesandbox.io/s/gracious-snow-1ypoe?file=/src/eventUsers.js

1 odpowiedź

+1 głos
odpowiedź 28 maja 2020 przez ScriptyChris Mędrzec (190,190 p.)
wybrane 28 maja 2020 przez poldeeek
 
Najlepsza

Nie mam doświadczenia w React, ale z dokumentacji state hook'a wynika, że drugi element tablicy zwracanej przez useState([]) - funkcja setMembers - służy do aktualizacji pierwszego elementu z tablicy (zmiennej members). Skoro console.log wypisujący "świeżą" wartość new_members pokazuje pustą tablicę, to obstawiam że przyczyną braku aktualizacji jest asynchroniczne uzupełnianie tablicy new_members (linia 18):

new_members.push(new_member)

Spróbuj umieścić:

setMembers(new_members)
console.log(members)

pod 18 linią (czyli na dole callbacka przekazanego do then) i powinno działać.

komentarz 28 maja 2020 przez poldeeek Mądrala (5,980 p.)
         props.event &&  props.event.uczestnicy.map( async member => {
            member.get().then(doc => {
                let new_member;
                new_member = {
                    ...doc.data(),
                    id: doc.id
                }
                new_members.push(new_member)
                setMembers(new_members)
            })
        })    

Zrozumiałem cię w ten sposób i na chwilę obecną wyświetla się tylko jeden użytkownik. 

komentarz 28 maja 2020 przez ScriptyChris Mędrzec (190,190 p.)

W którym miejscu wyświetla się tylko jeden użytkownik? Pokaż jeszcze w konsoli new_members oraz members po wywołaniu setMembers(new_members) w then.

A czy ten then odpala się za każdym razem gdy wykonujesz akcję dodawania użytkownika z aplikacji w przeglądarce? W then tworzony jest nowy member, dodawany do tablicy new_memers i na jej podstawie aktualizowana jest tablica members.

komentarz 28 maja 2020 przez poldeeek Mądrala (5,980 p.)

Ogólnie każda akutalizacja stanu - useState - setMembers() u nas wywołuje re-render interfejsu aplikacji, może to jest ważne. 

 

        props.event &&  props.event.uczestnicy.map(member => {
            member.get().then(doc => {
                let new_member;
                new_member = {
                    ...doc.data(),
                    id: doc.id
                }
                new_members.push(new_member)
                setMembers(new_members)
                console.log('new_members',new_members)
                console.log('members state', members)
            })

        }) 

Takie jest wyjście ostatnie w konsoli. Jednak w interfejsie aplikacji pokazuję się pierwszy z tych dwóch użytkowników. Dodatkowo React pozwala mi podejrzeć aktualny 'state' - czyli zawartość members w tym przypadku i jest on taki :

komentarz 28 maja 2020 przez ScriptyChris Mędrzec (190,190 p.)

Spróbuj w linii zapisać tak (funkcja aktualizująca stan przyjmuje callback, który jest odpalany po re-renderze i można w nim ponoć aktualizować state):

setMembers(prev => {
    prev.push(new_members);
    return prev;
});

Jeśli nie pomoże, to poszukaj w Google o aktualizacji state'u w React - ja, jak wspomniałem, nie mam w nim doświadczenia, więc w temacie wiem mniej niż Ty.

komentarz 28 maja 2020 przez poldeeek Mądrala (5,980 p.)
Też mi się wydaje, że problem leży bardziej po stronie React. No nic, będę próbował dalej. Dzięki za czas :P
1
komentarz 29 maja 2020 przez poldeeek Mądrala (5,980 p.)

Miałeś rację na początku. Problem był w asynchroniczności ustawiania użytkowników. Pomogło Promise.all :
 

    const getMembers = async () => {
        if(props.event) {
            const new_members  = await Promise.all(props.event.uczestnicy.map(member => {
                return member.get().then(doc => {
                    let new_member;
                    new_member = {
                        ...doc.data(),
                        id: doc.id
                    }
                    return new_member
                })
            }))
            setMembers(new_members)
        }
    }

 

komentarz 29 maja 2020 przez ScriptyChris Mędrzec (190,190 p.)

Super. :) Czyli teraz kod czeka na pobranie wszystkich uczestników i dopiero wtedy aktualizuje state, bo dotychczas map nie zwracał Promisa z nowo pozyskanym new_member.

Podobne pytania

0 głosów
0 odpowiedzi 312 wizyt
pytanie zadane 25 kwietnia 2020 w JavaScript przez poldeeek Mądrala (5,980 p.)
0 głosów
1 odpowiedź 206 wizyt
pytanie zadane 22 kwietnia 2020 w JavaScript przez poldeeek Mądrala (5,980 p.)
0 głosów
0 odpowiedzi 122 wizyt
pytanie zadane 15 marca 2020 w JavaScript przez poldeeek Mądrala (5,980 p.)

92,568 zapytań

141,422 odpowiedzi

319,641 komentarzy

61,957 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...