Tengo una lista de datos de mi firebase firestore que quiero exportar a .csv
Hice todo lo que se requiere, pero cuando agrego los valores que quiero exportar, siempre están indefinidos.
No soy un experto en reaccionar, soy algo intermedio, pero creo que es porque estoy configurando mis datos dentro de un useEffect Hook.
Mi estado de uso de datos no está definido, aunque contiene valores y puedo verlos en mi tabla, lo que hace que useState arroje errores.
¿Cómo permito que mis datos pasen a los encabezados?
Aquí está mi código:
const [data, setData] = useState([]); const [id, setID] = useState(""); const list = [] const filteredList = [] useEffect(() => { firebase.firestore().collection("Users").get().then((userSnapshot) => { userSnapshot.forEach((doc) => { const {powerAccount,first_name,registerDate,email,company,country,phone} = doc.data(); setID(doc.data().usersID) list.push({ usersID:doc.id, powerAccount:powerAccount, first_name:first_name, registerDate:registerDate, email:email, company:company, country:country, phone:phone, }); }); setData(list); }); },[]); const headers = [ // here all the keys give undefined. {label:'User',key:data.usersID}, {label:'Account',key:data.powerAccount}, {label:'Name',key:data.first_name}, {label:'RegistrationDate',key:data.registerDate}, {label:'Email',key:data.email}, {label:'Company',key:data.company}, {label:'Country',key:data.country}, {label:'Phone',key:data.phone}, ]; const csvReport = { filename:"userReport.csv", headers:headers, data: data // also my data useState is undefined, although it holds values and i can see them in my table } return ( <CSVLink {...csvReport} > Export </CSVLink> )Todos deben establecer la coordinación/actualización de useState y useEffect hooks y evitar depender de cualquier actualización de campo fuera del alcance de estos.
Luego debe eliminar la variable de list , mover la actualización de estado a su gancho de efecto y consolidar todos los datos de los usuarios en la misma estructura:
const [data, setData] = useState([]); useEffect(() => { firebase.firestore() .collection("Users") .get() .then((userSnapshot) => { const usersData = []; userSnapshot.forEach((doc) => { const { powerAccount, first_name, registerDate, email, company, country, phone, userID } = doc.data(); const userData = { usersID: doc.id, powerAccount: powerAccount, first_name: first_name, registerDate: registerDate, email: email, company: company, country: country, phone: phone, }; const headers = [ // here all the keys give undefined. { label: 'User', key: userID }, { label: 'Account', key: powerAccount }, { label: 'Name', key: first_name }, { label: 'RegistrationDate', key: registerDate }, { label: 'Email', key: email }, { label: 'Company', key: company }, { label: 'Country', key: country }, { label: 'Phone', key: phone }, ]; const csvReport = { filename: "userReport.csv", headers: headers, data: userData } usersData.push(csvReport); }); setData(usersData); }); }, []); return ( <CSVLink {...data} > Export </CSVLink> )Es posible que necesite agregar el estado de carga para reflejar el efecto de la interfaz de usuario de los datos que se cargan.
De acuerdo con su implementación, la obtención de datos de Firebase es asíncrona, por lo que csvData no está definido porque no se actualiza después de una actualización de estado. Intente cambiar su código de esta manera y avíseme si funciona bien.
const [data, setData] = useState({ filename: "userReport.csv", headers: [], data: [], }); const [id, setID] = useState(""); const filteredList = []; useEffect(() => { firebase .firestore() .collection("Users") .get() .then((userSnapshot) => { let list = []; userSnapshot.forEach((doc) => { const { powerAccount, first_name, registerDate, email, company, country, phone, } = doc.data(); setID(doc.data().usersID); list.push({ usersID: doc.id, powerAccount: powerAccount, first_name: first_name, registerDate: registerDate, email: email, company: company, country: country, phone: phone, }); }); const headers = [ // I'm not sure why you need this key // but if it's only for uniqueness // you can replace them by unique strings like // { label: "User", key: "user" }, // { label: "Account", key: "account" }, { label: "User", key: data.usersID }, { label: "Account", key: data.powerAccount }, { label: "Name", key: data.first_name }, { label: "RegistrationDate", key: data.registerDate }, { label: "Email", key: data.email }, { label: "Company", key: data.company }, { label: "Country", key: data.country }, { label: "Phone", key: data.phone }, ]; const csvReport = { filename: "userReport.csv", headers: headers, data: list, }; setData(csvReport); }); }, []); return <CSVLink {...data}>Export</CSVLink>;Creo que hay dos cosas que causan el problema que debes entender.
La obtención de datos de firebase es asíncrona y puede llevar algún tiempo antes de que obtenga los datos devueltos mientras ha guardado csvReport como variables constantes y lo ha configurado como propiedades del elemento React. Entonces, cuando firebase todavía está cargando sus datos y su componente de reacción ya está renderizado/montado, su estado de data tiene un valor de [] desde el valor predeterminado como se define en la declaración useState . Según su código, su variable constante csvReport no recibirá nuevos datos de firebase a menos que su aplicación se vuelva a procesar (ingrese el nuevo ciclo de vida y repita). Por ejemplo, cambiar a otro componente de pestaña y volver a este componente sin actualizar el navegador.
const csvReport = { filename:"userReport.csv", headers:headers, => [{ label: "User", key: undefined }, ...etc]; undefined bcs `data` is [] data: data => the value is [] }Entonces, la solución simple es NO guardar los datos como una variable constante y configurar las propiedades del elemento React directamente desde su variable useState. Según su código, haría algunos cambios como este.
...your previous code const getHeaders = () => { // Do your data manipulation using `data` in useState // For example: const headers = data && data.map(item => {return {id: item.id}}) return headers } return ( <CSVLink filename="userReport.csv" headers={getHeaders()} data={data} > Export </CSVLink> )Espero que esto ayude y diviértete haciendo cambios :)