React Hooks в сочетании с данными Firebase, не отображаемыми при загрузке страницы - PullRequest
0 голосов
/ 24 марта 2019

Я хочу использовать функциональность React Hooks в сочетании с Firebase. Но теперь, когда данные установлены, результат виден только при обновлении DOM. Мой текущий код:

import React, { useState, useEffect } from 'react';
import firebase, { getPivotFunction } from '../../firebase';

/**
* Return a styled component
*/
const ListCards = () => {
  const [data, setData] = useState([]);

  const userListsRef = firebase
    .database()
    .ref('userLists')
    .child('1234d343f');

  useEffect(() => {
    (async function() {
       try {
         const response = await getPivotFunction(userListsRef, 'lists');
         setData(response);
       } catch (e) {
         console.error(e);
       }
    })();
  }, []);

 /**
 * Return all list cards
 */
 return (
  <ul>
    {data.map(item => (
      <li key={item.time}>dummy text</li>
    ))}
  </ul>
 );
};

Когда страница отображается в первый раз, «фиктивный текст» не отображается, только когда запускается обновление. Моя цель - сделать так, чтобы «фиктивный текст» появлялся, когда страница загружена, и data не имеет длины 0.

В этом случае getPivotFunction содержит:

/** Get FireBase data based on a pivot table */
const getPivotFunction = (ref, target) => {
  let dataArray = [];

  ref.once('value', userInfo => {
    userInfo.forEach(function(result) {
      firebase
        .database()
        .ref(target)
        .child(result.key)
        .on('value', snapshot => {
          dataArray.push(snapshot.val());
        });
    });
  });

  return dataArray;
};

Пожалуйста, дайте мне знать

Ответы [ 2 ]

2 голосов
/ 24 марта 2019

Ваш getPivotFunction является асинхронной функцией, которая опирается на обратный вызов, и использование асинхронного ожидания не является правильным подходом. Вместо этого вам нужен обратный звонок

/** Get FireBase data based on a pivot table */
const getPivotFunction = (ref, target, callback) => {
  const dataArray= [];
  ref.once('value', userChats => {
    var i = 0;
    userChats.forEach(function(result) {
      firebase
        .database()
        .ref(target)
        .child(result.key)
        .on('value', snapshot => {
          i++;
          dataArray.push(snapshot.val());
          if(i === userChats.length) {
             callback(dataArray)
          }
        });
    });
  });
};

и используйте его как

/**
* Return a styled component
*/
const ListCards = () => {
  const [data, setData] = useState([]);

  const userListsRef = firebase
    .database()
    .ref('userLists')
    .child('1234d343f');

  useEffect(() => {
      getPivotFunction(userListsRef, 'lists', (response) => {
         setData(response);
      });
  }, []);

 /**
 * Return all list cards
 */
 return (
  <ul>
    {data.map(item => (
      <li key={item.time}>dummy text</li>
    ))}
  </ul>
 );
};
0 голосов
/ 24 марта 2019

Хуки не предназначены для работы с такими асинхронными функциями.Примерно так должно работать:

const ListCards = () => {
  const [data, setData] = useState([]);
  const [loaded, setLoaded] = useState(false);

  ... 

  useEffect(() => {
    getPivotFunction(userListsRef, 'lists')
    .then(data => { setData(data); setLoaded(true)});
  }, []);
};

Тогда рендерится только тогда, когда loaded равно true.

...