Я пытаюсь показать список пользователей, получаемый из базы данных Firebase Realtime. По журналам я их всех получаю! Но на экране появляется только первый. Если я поставлю в качестве зависимости users
, я получаю бесконечное l oop в журналах, но все еще один элемент на экране. useCallback
тоже не помогло. Если я заполню поля ввода на экране, тем самым запустив повторный рендеринг, я получу всех пользователей. Почему это не ставит их всех в первую очередь? Может быть, что-то с Typescript?
Спасибо!
...
const [users, setUsers] = useState<any[]>([]);
const [usersRef] = useState<any>(firebase.database().ref().child('users'));
...
const getUsers: () => void = useCallback(() => {
const loadedUsers: any[] = []
usersRef.on('child_added', (snap: any) => {
loadedUsers.push(snap.val())
setUsers(loadedUsers)
console.log('loadedUsers', loadedUsers);
})
}, [setUsers, usersRef])
useEffect(() => {
getUsers();
return () => usersRef.off()
}, [usersRef, getUsers])
const displayUsers = (users: any) => {
console.log(users);
return users.length > 0 && users.map((user: any) =>
<li key={user.id}>
{user.email}
</li>
)
}
...
<ul>
{displayUsers(users)}
</ul>
Итак, благодаря @Renaud Tarne c, это оказалась проблема со слушателем firebase. Пришлось слушать изменение value
вместо child_added
. Ниже новая версия. Не очень нравится, каким оказался displayUsers
, но работает. Если у кого-то есть предложения, я был бы рад увидеть.
Еще раз спасибо!
const getUsers: () => void = useCallback(() => {
const loadedUsers: any[] = []
usersRef.on('value', (snap: any) => {
loadedUsers.push(snap.val())
setUsers(loadedUsers)
console.log('loadedUsers', loadedUsers);
})
}, [setUsers, usersRef])
...
const displayUsers = (users: any) => {
console.log(users);
return users.length > 0 && users.map((userObj: any) => {
const users = []
for (const key in userObj) {
users.push(userObj[key])
}
return users.map((user: any) =>
<li key={user.id}>
{user.email}
</li>
)
}
)
}