【问题标题】:React renders only one item from list downloaded from firebaseReact 只渲染从 firebase 下载的列表中的一项
【发布时间】:2020-11-27 12:34:24
【问题描述】:

我正在尝试显示从 Firebase 实时数据库获取的用户列表。在日志上我得到了所有!但在屏幕上,只出现了第一个。如果我将 users 作为依赖项,我会在日志上看到一个无限循环,但屏幕上仍然有一个项目。 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 Tarnec,事实证明这是 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>
      )
    }
    )
  }

【问题讨论】:

    标签: reactjs typescript firebase firebase-realtime-database


    【解决方案1】:

    如果我正确理解您的问题,这是因为您使用了child_added 事件而不是value 事件。两者的区别见doc

    价值事件

    此事件将触发一次,初始数据存储在此 位置,然后每次数据变化时再次触发。这 传递给回调的 DataSnapshot 将用于 on() 被调用..

    child_added 事件

    此事件将为每个初始孩子触发一次 位置,每次有新孩子时都会再次触发 添加。传入回调的 DataSnapshot 将反映数据 为相关的孩子。

    总之,通过value 事件,您可以获得该位置的所有数据,而通过child_added 事件,您可以获得孩子的数据。

    【讨论】:

    • 感谢您的宝贵时间。我将在上面设置完成的代码。我会更好地查看文档!
    猜你喜欢
    • 2017-01-19
    • 2017-11-16
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多