Обновления Firestore в реальном времени для таблицы пользовательского интерфейса материалов - PullRequest
0 голосов
/ 12 июля 2020

Итак, мой текущий код приведен ниже. Я пытаюсь обновить таблицу пользовательского интерфейса материалов в реальном времени с помощью информации из базы данных firestore. Я могу читать информацию из базы данных и вставлять ее в массив, но когда я устанавливаю данные таблицы равными массиву, это ничего не меняет. Я читал, что для этого мне следует использовать состояния, но я новичок в React / JS и не совсем уверен, как реализовать это в моей текущей ситуации. Любая помощь или указатели будут очень признательны!

EDITED

Я реализовал ответ от @Mateen, но код успешно компилируется, но в самом приложении появляется следующая ошибка вверх.

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

Firebase. js

import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";

const firebaseConfig = {******};


export const myFirebase = firebase.initializeApp(firebaseConfig);
const baseDb = myFirebase.firestore();
export const db = baseDb;

let ref = db.collection('AQ-gear-distribution');
let peopleref = db.collection('users');

var tempname;
var tempclass;
var tempitem;
var tempdate;
var tempentry;

var tableInfo;

function createData(name, classs, item, date) {
  return { name, classs, item, date };
}

let ref = db.collection('AQ-gear-distribution');
let peopleref = db.collection('users');

var tempname;
var tempclass;
var tempitem;
var tempdate;
var tempentry;

function createData(name, classs, item, date) {
  return { name, classs, item, date };
}

export function Populate() {
  const [data, setData] = useState("");
  useEffect(() => {
    const data2 = [];
    ref.onSnapshot(snapshot => {
      snapshot.forEach(doc => {
        tempname = doc.data().user;
        tempitem = doc.data().item;
        tempdate = doc.data().date;
        peopleref.where('username', '==', tempname).get().then(function(querySnapshot){
          querySnapshot.forEach(function(doc2) {
            if(doc2.empty)
            {
              tempclass = "Unknown";
            } else {
              tempclass = doc2.data().class;
            }
          });
          tempname = doc.data().user;
          tempitem = doc.data().item;
          tempdate = doc.data().date;
          tempentry = createData(tempname, tempclass, tempitem, tempdate);
          console.log(data2);
          data2.push(tempentry);
        });
      });
    });
    setData(data2)
  }, [])
  return (data)
}

DenseTable. js


//This is the core of my table file

const rows = Populate();



export default function EnhancedTable() {
  const classes = useStyles();
  const [order, setOrder] = React.useState('asc');
  const [orderBy, setOrderBy] = React.useState('classs');
  const [selected, setSelected] = React.useState([]);

  const handleRequestSort = (event, property) => {
    const isAsc = orderBy === property && order === 'asc';
    setOrder(isAsc ? 'desc' : 'asc');
    setOrderBy(property);
  };

  const handleSelectAllClick = (event) => {
    if (event.target.checked) {
      const newSelecteds = rows.map((n) => n.name);
      setSelected(newSelecteds);
      return;
    }
    setSelected([]);
  };

  const handleClick = (event, name) => {
    const selectedIndex = selected.indexOf(name);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, name);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1),
      );
    }

    setSelected(newSelected);
  };

  const isSelected = (name) => selected.indexOf(name) !== -1;

  return (
    <div className={classes.root}>
      <Paper className={classes.paper}>
        <EnhancedTableToolbar numSelected={selected.length} />
        <TableContainer>
          <Table
            className={classes.table}
            aria-labelledby="tableTitle"
            size={'medium'}
            aria-label="enhanced table"
          >
            <EnhancedTableHead
              classes={classes}
              numSelected={selected.length}
              order={order}
              orderBy={orderBy}
              onSelectAllClick={handleSelectAllClick}
              onRequestSort={handleRequestSort}
              rowCount={rows.length}
            />
            <TableBody>
              {stableSort(rows, getComparator(order, orderBy))
                .map((row, index) => {
                  const isItemSelected = isSelected(row.name);
                  const labelId = `enhanced-table-checkbox-${index}`;

                  return (
                    <StyledTableRow
                      hover
                      onClick={(event) => handleClick(event, row.name)}
                      role="checkbox"
                      aria-checked={isItemSelected}
                      tabIndex={-1}
                      key={row.name}
                      selected={isItemSelected}
                    >
                      <StyledTableCell padding="checkbox">
                        <Checkbox
                          checked={isItemSelected}
                          inputProps={{ 'aria-labelledby': labelId }}
                        />
                      </StyledTableCell>
                      <StyledTableCell component="th" id={labelId} scope="row" padding="none">
                        {row.name}
                      </StyledTableCell>
                      <StyledTableCell align="right">{row.classs}</StyledTableCell>
                      <StyledTableCell align="right">{row.item}</StyledTableCell>
                      <StyledTableCell align="right">{row.date}</StyledTableCell>
                    </StyledTableRow>
                  );
                })}
            </TableBody>
          </Table>
        </TableContainer>
      </Paper>
    </div>
  );
}


1 Ответ

0 голосов
/ 12 июля 2020

Вы хотите отображать обновленные данные таблицы, если для них заданы данные, полученные из firebase. В React для повторного рендеринга компонента вам необходимо обновить свойства / состояние, другие - принудительное обновление. В случае с вами, поддерживает состояние (на useState, если вы используете function component) и обновляет это состояние, когда ваши данные будут готовы, и реакция отобразит компонент.

Демо псевдо:

const myTable = () => {
    const [data, setData] = useState("");
    useEffect(() => {
      // fetch your data here
      // when data is ready setData(<fetched data>)}, 
    [])
    return (<TableCell>{data}<TableCell>)
}

Теперь, если data обновляется путем вызова setData, myTable будет повторно отображен.

Обновлено:

В const rows = Populate(); вы вызываете функциональный компонент? Настоятельно рекомендуется визуализировать (<Populate />) компоненты вместо того, чтобы вызывать их напрямую. Вызов Function Component напрямую приводит к ошибкам и ошибкам. Причина была объяснена здесь: Не вызывать компонент функции React

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...