首页 > 解决方案 > 如何使数据在刷新 React JS 时保持不变?

问题描述

我有一个代码,我在其中安装了一个带有一些 firebase 数据的表,但由于某种原因,这些值消失了,我在接下来的两周里一直在努力解决这个问题,我还没有找到解决方案,我已经问过两次了到目前为止,我已经尝试了所有方法,但它一直在消失。

重要更新 我只想澄清以下显然我错了问题不是因为它是另一个问题中提到的嵌套集合。问题是因为当我刷新时我的“用户”在这个过程中迷路了。

我将用户从登录带到应用程序,如下所示:

<Estudiantes user={user} />

然后我收到它作为道具 function ListadoPedidos({user})

但是迷路了,因为当我尝试将我的firebase用作时迷路了:

estudiantesRef = db.collection("usuarios").doc(user.uid).collection("estudiantes")

由于用户“丢失”了,因此 uid 将为空。由于为 null 它永远不会到达集合和文档。

标签: reactjsfirebasegoogle-cloud-firestorelocal-storagerefresh

解决方案


我有一个简单的解决方案给你。只需将 localStorage 的解析提高一级,将 preloadedState 作为 prop 传递到您的组件中,然后使用它来初始化您的 state 变量。

const ListadoEstudiantes = (props) => {
  const estData = JSON.parse(window.localStorage.getItem('estudiantes'));
  return <Listado preloadedState={estData} {...props} />;
};

然后用 prop 初始化 state

  const initialState = props.preloadedState || [];
  const [estudiantesData, setEstudiantesData] = useState(initialState);

最后,更新 useEffect 钩子以在状态更改时保持状态。

  useEffect(() => {
    window.localStorage.setItem('estudiantes', JSON.stringify(estudiantes));
  }, [estudiantes]);

完整代码

import React, { useState, useEffect } from 'react';
import { db } from './firebase';
import { useHistory } from 'react-router-dom';
import './ListadoEstudiantes.css';
import {
  DataGrid,
  GridToolbarContainer,
  GridToolbarFilterButton,
  GridToolbarDensitySelector,
} from '@mui/x-data-grid';
import { Button, Container } from '@material-ui/core';
import { IconButton } from '@mui/material';
import PersonAddIcon from '@mui/icons-material/PersonAddSharp';
import ShoppingCartSharpIcon from '@mui/icons-material/ShoppingCartSharp';
import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined';
import { Box } from '@mui/system';

const ListadoEstudiantes = (props) => {
  const estData = JSON.parse(window.localStorage.getItem('estudiantes'));
  return <Listado preloadedState={estData} {...props} />;
};

const Listado = ({ user, preloadedState }) => {
  const history = useHistory('');
  const crearEstudiante = () => {
    history.push('/Crear_Estudiante');
  };

  const initialState = preloadedState || [];
  const [estudiantesData, setEstudiantesData] = useState(initialState);

  const parseData = {
    pathname: '/Crear_Pedidos',
    data: estudiantesData,
  };

  const realizarPedidos = () => {
    if (estudiantesData == 0) {
      window.alert('Seleccione al menos un estudiante');
    } else {
      history.push(parseData);
    }
  };

  function CustomToolbar() {
    return (
      <GridToolbarContainer>
        <GridToolbarFilterButton />
        <GridToolbarDensitySelector />
      </GridToolbarContainer>
    );
  }

  const [estudiantes, setEstudiantes] = useState([]);
  const [selectionModel, setSelectionModel] = useState([]);
  const columns = [
    { field: 'id', headerName: 'ID', width: 100 },

    { field: 'nombre', headerName: 'Nombre', width: 200 },

    { field: 'colegio', headerName: 'Colegio', width: 250 },

    { field: 'grado', headerName: 'Grado', width: 150 },
    {
      field: 'delete',
      width: 75,
      sortable: false,
      disableColumnMenu: true,
      renderHeader: () => {
        return (
          <IconButton
            onClick={() => {
              const selectedIDs = new Set(selectionModel);
              estudiantes
                .filter((x) => selectedIDs.has(x.id))
                .map((x) => {
                  db.collection('usuarios')
                    .doc(user.uid)
                    .collection('estudiantes')
                    .doc(x.uid)
                    .delete();
                });
            }}
          >
            <DeleteOutlinedIcon />
          </IconButton>
        );
      },
    },
  ];

  const deleteProduct = (estudiante) => {
    if (window.confirm('Quiere borrar este estudiante ?')) {
      db.collection('usuarios').doc(user.uid).collection('estudiantes').doc(estudiante).delete();
    }
  };

  useEffect(() => {}, [estudiantesData]);

  const estudiantesRef = db.collection('usuarios').doc(user.uid).collection('estudiantes');
  useEffect(() => {
    estudiantesRef.onSnapshot((snapshot) => {
      const tempData = [];
      snapshot.forEach((doc) => {
        const data = doc.data();
        tempData.push(data);
      });
      setEstudiantes(tempData);
      console.log(estudiantes);
    });
  }, []);

  useEffect(() => {
    window.localStorage.setItem('estudiantes', JSON.stringify(estudiantes));
  }, [estudiantes]);

  return (
    <Container fixed>
      <Box mb={5} pt={2} sx={{ textAlign: 'center' }}>
        <Button
          startIcon={<PersonAddIcon />}
          variant="contained"
          color="primary"
          size="medium"
          onClick={crearEstudiante}
        >
          Crear Estudiantes
        </Button>
        <Box pl={25} pt={2} mb={2} sx={{ height: '390px', width: '850px', textAlign: 'center' }}>
          <DataGrid
            rows={estudiantes}
            columns={columns}
            pageSize={5}
            rowsPerPageOptions={[5]}
            components={{
              Toolbar: CustomToolbar,
            }}
            checkboxSelection
            //Store Data from the row in another variable
            onSelectionModelChange={(id) => {
              setSelectionModel(id);
              const selectedIDs = new Set(id);
              const selectedRowData = estudiantes.filter((row) => selectedIDs.has(row.id));
              setEstudiantesData(selectedRowData);
            }}
            {...estudiantes}
          />
        </Box>
        <Button
          startIcon={<ShoppingCartSharpIcon />}
          variant="contained"
          color="primary"
          size="medium"
          onClick={realizarPedidos}
        >
          Crear pedido
        </Button>
      </Box>
    </Container>
  );
};


推荐阅读