reactjs - 如何使数据在刷新 React JS 时保持不变?
问题描述
我有一个代码,我在其中安装了一个带有一些 firebase 数据的表,但由于某种原因,这些值消失了,我在接下来的两周里一直在努力解决这个问题,我还没有找到解决方案,我已经问过两次了到目前为止,我已经尝试了所有方法,但它一直在消失。
重要更新 我只想澄清以下显然我错了问题不是因为它是另一个问题中提到的嵌套集合。问题是因为当我刷新时我的“用户”在这个过程中迷路了。
我将用户从登录带到应用程序,如下所示:
<Estudiantes user={user} />
然后我收到它作为道具
function ListadoPedidos({user})
但是迷路了,因为当我尝试将我的firebase用作时迷路了:
estudiantesRef = db.collection("usuarios").doc(user.uid).collection("estudiantes")
由于用户“丢失”了,因此 uid 将为空。由于为 null 它永远不会到达集合和文档。
解决方案
我有一个简单的解决方案给你。只需将 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>
);
};
推荐阅读
- for-loop - 使用 nunjucks 的“for”循环中的用户“elif”
- python - 从一个字典创建数据框并删除特定字符
- c++ - ifstream: /dev/stdin 与 std::cin 的工作方式不同
- powershell - 如何提取句点、星号和单词之间的字符串
- python - 如何使用网络抓取或 IMDbPY 来获取演员 Instagram 帐户的链接?
- java - 为什么签名指定接口时调用超类方法?
- json - 打印对象中不同条目的键和值
- google-chrome - 如何使用 Chrome DevTools 协议访问 XHR 请求?
- laravel - 普通 Web 和 API 中间件的 Laravel Echo 身份验证
- plot - 牛虻中的水平线