试图将数据从我的firebase数据导出到csv文件会产生未定义的结果



我有一个来自firebase firestore的数据列表,我想将其导出到.csv

我做了所有需要的事情,但当我添加要导出的值时,它们总是未定义的。

我不是反应方面的专家,我有点中等,但我认为这是因为我在useEffect Hook.中设置数据

我的数据useState是未定义的,尽管它包含值,并且我可以在表中看到它们,这导致CSVLink抛出错误。

如何允许我的数据传递到标头中?

这是我的代码:

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>
)

根据您的实现,从firebase获取数据是异步的,因此csvData未定义,因为它在状态更新后没有更新试着这样更改你的代码,让我知道它是否工作良好

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>;

您应该将所有状态协调/更新到useStateuseEffect挂钩,并避免依赖这些挂钩范围之外的任何字段更新。

然后,您应该删除list变量,将状态更新移动到效果挂钩,并将所有用户数据合并到同一结构中:

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>
)

您可能需要添加加载状态来反映正在加载的数据的UI效果。

我认为有两件事会导致您需要理解的问题。

  1. 异步函数
  2. React生命周期

从firebase获取数据是异步的,当您将csvReport保存为常量变量并将其设置为React元素属性时,可能需要一段时间才能获得返回的数据。因此,当firebase仍在加载数据,并且react组件已经渲染/装载时,data状态的值为[],而不是useState语句中定义的默认值。根据您的代码,除非您的应用程序被重新呈现(输入新的生命周期并重复(,否则csvReport常量变量将不会从firebase接收新数据。例如,切换到其他选项卡组件并返回到此组件而不刷新浏览器。

const csvReport = {
filename:"userReport.csv",
headers:headers, => [{ label: "User", key: undefined }, ...etc]; undefined bcs `data` is []
data: data => the value is []
}

因此,简单的解决方案是NOT将数据保存为常量变量,并直接从useState变量设置React元素属性。根据你的代码,我会做一些这样的更改。

...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>
)

希望这有助于做出改变,并从中获得乐趣:(

最新更新