如何在 setState() 之后将 Firebase 数据提取到变量中?
How to extract Firebase data to variable after setState() with react?
第一次使用 React 和 firebase real-time 数据库。我很难提取数据并将其插入到 const 项中。据我了解,firebase代码是异步的,所以代码会在页面加载完成后执行。
多次检查控制台后,我看到数据加载到 const tasks 数组中。但是,当我将它放入项目数组(标题、副标题等)中时,任务 [] 中的数据不会显示。我已经查看了多种解决方案,其中 none 已经回答了我的问题。
我以为是因为item是const,改成var后问题依旧。任何形式的指导都将不胜感激。
一个小提示:使用 await 似乎对我不起作用。由于我对 firebase + react 缺乏了解,我可能会把事情搞混。
const Timelines = () => {
const [tasks, setTasks] = useState([]);
useEffect(() => {
const ref = firebase.database().ref();
const listener = ref.on('value', snapshot => {
const fetchedTasks = [];
snapshot.forEach(childSnapshot => {
const key = childSnapshot.key; //using await here doesn't work. Return 'await is a reserved word error'
const data = childSnapshot.val(); //using await here doesn't work. Return 'await is a reserved word error'
fetchedTasks.push({ id: key, ...data });
});
setTasks(fetchedTasks);
});
return () => ref.off('value', listener);
}, [firebase.database()]);
const items = [{
title: "Header" + tasks,
cardTitle: "Title",
//url: "http://www.history.com",
cardSubtitle: "LA",
cardDetailedText: ["Paragrah"],
media: {
type: "IMAGE",
source: {
url: "./images/image1.jpeg"
}
}
},
{
title: "Title",
cardTitle: "Title1",
//url: "http://www.history.com",
cardSubtitle: "LA",
cardDetailedText: "Paragraph 1",
media: {
type: "IMAGE",
source: {
url: "./images/img-2.jpg"
}
}
},
]
return (
<div className='timeline' style={{ width: "auto", height: "auto" }}>
<Chrono items={items}
slideShow
mode="VERTICAL_ALTERNATING"
theme={{
primary: "#7e8083",
secondary: "white",
cardBgColor: "#00467f",
cardForeColor: "white",
titleColor: "#00467f"
}}
useReadMore="true" />
</div>
)
};
export default Timelines;
您的问题可能是重新渲染问题。所以你可以尝试加载状态。检查我的 useEffect 和 return.
const Timelines = () => {
const [tasks, setTasks] = useState([]);
const [loading, setLoading] = useState(false); //<----
useEffect(() => {
setLoading(true) //<-----
const ref = firebase.database().ref();
const listener = ref.on('value', snapshot => {
const fetchedTasks = [];
snapshot.forEach(childSnapshot => {
const key = childSnapshot.key; //using await here doesn't work. Return 'await is a reserved word error'
const data = childSnapshot.val(); //using await here doesn't work. Return 'await is a reserved word error'
fetchedTasks.push({ id: key, ...data });
});
setTasks(fetchedTasks);
setLoading(false) //<---
});
return () => ref.off('value', listener);
}, [firebase.database()]);
const items = [{
title: "Header" + tasks,
cardTitle: "Title",
//url: "http://www.history.com",
cardSubtitle: "LA",
cardDetailedText: ["Paragrah"],
media: {
type: "IMAGE",
source: {
url: "./images/image1.jpeg"
}
}
},
{
title: "Title",
cardTitle: "Title1",
//url: "http://www.history.com",
cardSubtitle: "LA",
cardDetailedText: "Paragraph 1",
media: {
type: "IMAGE",
source: {
url: "./images/img-2.jpg"
}
}
},
]
return !loading && (
<div className='timeline' style={{ width: "auto", height: "auto" }}>
<Chrono items={items}
slideShow
mode="VERTICAL_ALTERNATING"
theme={{
primary: "#7e8083",
secondary: "white",
cardBgColor: "#00467f",
cardForeColor: "white",
titleColor: "#00467f"
}}
useReadMore="true" />
</div>
)
};
export default Timelines;
谢谢
Gökhan Geyik 所说的解决方案是正确的。但是我不得不稍微调整我的代码,因为我的 Firebase 数据库结构不同。问题是,重新渲染!
useEffect(() => {
setLoading(true)
const ref = firebase.database().ref('Overview/events');
const listener = ref.on('value', snapshot => {
const fetchedTasks = [];
const data = snapshot.val();
fetchedTasks.push(data);
setTasks(fetchedTasks);
setLoading(false)
});
return () => ref.off('value', listener);
}, [firebase.database()]);
return !loading && (
....
)
这很有效。非常感谢 Gökhan Geyik 的正确方向!
第一次使用 React 和 firebase real-time 数据库。我很难提取数据并将其插入到 const 项中。据我了解,firebase代码是异步的,所以代码会在页面加载完成后执行。
多次检查控制台后,我看到数据加载到 const tasks 数组中。但是,当我将它放入项目数组(标题、副标题等)中时,任务 [] 中的数据不会显示。我已经查看了多种解决方案,其中 none 已经回答了我的问题。
我以为是因为item是const,改成var后问题依旧。任何形式的指导都将不胜感激。
一个小提示:使用 await 似乎对我不起作用。由于我对 firebase + react 缺乏了解,我可能会把事情搞混。
const Timelines = () => {
const [tasks, setTasks] = useState([]);
useEffect(() => {
const ref = firebase.database().ref();
const listener = ref.on('value', snapshot => {
const fetchedTasks = [];
snapshot.forEach(childSnapshot => {
const key = childSnapshot.key; //using await here doesn't work. Return 'await is a reserved word error'
const data = childSnapshot.val(); //using await here doesn't work. Return 'await is a reserved word error'
fetchedTasks.push({ id: key, ...data });
});
setTasks(fetchedTasks);
});
return () => ref.off('value', listener);
}, [firebase.database()]);
const items = [{
title: "Header" + tasks,
cardTitle: "Title",
//url: "http://www.history.com",
cardSubtitle: "LA",
cardDetailedText: ["Paragrah"],
media: {
type: "IMAGE",
source: {
url: "./images/image1.jpeg"
}
}
},
{
title: "Title",
cardTitle: "Title1",
//url: "http://www.history.com",
cardSubtitle: "LA",
cardDetailedText: "Paragraph 1",
media: {
type: "IMAGE",
source: {
url: "./images/img-2.jpg"
}
}
},
]
return (
<div className='timeline' style={{ width: "auto", height: "auto" }}>
<Chrono items={items}
slideShow
mode="VERTICAL_ALTERNATING"
theme={{
primary: "#7e8083",
secondary: "white",
cardBgColor: "#00467f",
cardForeColor: "white",
titleColor: "#00467f"
}}
useReadMore="true" />
</div>
)
};
export default Timelines;
您的问题可能是重新渲染问题。所以你可以尝试加载状态。检查我的 useEffect 和 return.
const Timelines = () => {
const [tasks, setTasks] = useState([]);
const [loading, setLoading] = useState(false); //<----
useEffect(() => {
setLoading(true) //<-----
const ref = firebase.database().ref();
const listener = ref.on('value', snapshot => {
const fetchedTasks = [];
snapshot.forEach(childSnapshot => {
const key = childSnapshot.key; //using await here doesn't work. Return 'await is a reserved word error'
const data = childSnapshot.val(); //using await here doesn't work. Return 'await is a reserved word error'
fetchedTasks.push({ id: key, ...data });
});
setTasks(fetchedTasks);
setLoading(false) //<---
});
return () => ref.off('value', listener);
}, [firebase.database()]);
const items = [{
title: "Header" + tasks,
cardTitle: "Title",
//url: "http://www.history.com",
cardSubtitle: "LA",
cardDetailedText: ["Paragrah"],
media: {
type: "IMAGE",
source: {
url: "./images/image1.jpeg"
}
}
},
{
title: "Title",
cardTitle: "Title1",
//url: "http://www.history.com",
cardSubtitle: "LA",
cardDetailedText: "Paragraph 1",
media: {
type: "IMAGE",
source: {
url: "./images/img-2.jpg"
}
}
},
]
return !loading && (
<div className='timeline' style={{ width: "auto", height: "auto" }}>
<Chrono items={items}
slideShow
mode="VERTICAL_ALTERNATING"
theme={{
primary: "#7e8083",
secondary: "white",
cardBgColor: "#00467f",
cardForeColor: "white",
titleColor: "#00467f"
}}
useReadMore="true" />
</div>
)
};
export default Timelines;
谢谢
Gökhan Geyik 所说的解决方案是正确的。但是我不得不稍微调整我的代码,因为我的 Firebase 数据库结构不同。问题是,重新渲染!
useEffect(() => {
setLoading(true)
const ref = firebase.database().ref('Overview/events');
const listener = ref.on('value', snapshot => {
const fetchedTasks = [];
const data = snapshot.val();
fetchedTasks.push(data);
setTasks(fetchedTasks);
setLoading(false)
});
return () => ref.off('value', listener);
}, [firebase.database()]);
return !loading && (
....
)
这很有效。非常感谢 Gökhan Geyik 的正确方向!