【发布时间】:2020-06-22 18:57:42
【问题描述】:
我对 React 和 Firebase 比较陌生。我阅读了几篇关于处理返回承诺或接受回调的异步函数是多么麻烦的文章,而且我知道的最终输出“正确”显示的方法很少。我正在为我的项目处理许多异步方法。据我所知,进行异步调用和放置事件侦听器的最佳位置是componentDidMount 和componentDidUpdate,因此我有一个非常轻量级的构造函数、渲染方法,并尝试将我的大部分异步调用压缩为并将我的实时数据库监听器放在那里。目前这些是我编写componentDidMount 和componentDidUpdate 代码的sn-ps。
async componentDidMount() {
console.log("Component did mount happen");
const channels_value = await f1();
const change_object = {};
change_object[MESSENGER_CHANNELS] = channels_value;
if (this.state[MESSENGER_ACTIVE_CHANNEL_ID]) {
const channel_data = await f2();
const members_value = channel_data["ids"];
const channel_title_value = channel_data["name"];
change_object["ids"] = members_value;
change_object["name"] = channel_title_value;
//Listener for upcoming messages
realtime_db.ref(`${MESSAGES_REALTIME_REFERENCE}/${this.state[MESSENGER_ACTIVE_CHANNEL_ID]}`)
.orderByChild(MESSAGE_CREATE_TIMESTAMP)
.on("value", (snapshot) => {
const messages = [];
snapshot.forEach((snap) => {
const obj = snap.val();
obj[MESSAGE_ID] = snap.key;
messages.push(obj);
});
const new_state = {};
new_state[MESSENGER_MESSAGES] = messages;
console.log("New state");
console.log(new_state);
this.setState(new_state);
});
}
this.setState(change_object);
//some event listeners that should persist until destroyed
}
async componentDidUpdate() {
//Allows reloading
console.log("ComponentDidUpdate occurred");
const change_object = {};
let boolean_one = false;
let boolean_two = false;
let boolean_three = false;
if (this.state[CHANNEL_ID]) {
const channel_data = await f2();
const members_value = channel_data["ids"];
const channel_title_value = channel_data["name"];
change_object["ids"] = members_value;
change_object["name"] = channel_title_value;
//Listener for upcoming messages
await realtime_db.ref(`${MESSAGES_REALTIME_REFERENCE}/${this.state[MESSENGER_ACTIVE_CHANNEL_ID]}`)
.orderByChild(MESSAGE_CREATE_TIMESTAMP)
.on("value", (snapshot) => {
//Currently handling all setState logic inside the callback function to output correctly
const messages = [];
snapshot.forEach((snap) => {
const obj = snap.val();
obj[MESSAGE_ID] = snap.key;
messages.push(obj);
});
//some code for deciding whether to set state
const deciding_boolean = boolean_three || boolean_one && boolean_two;
if (deciding_boolean) {
this.setState(change_object);
}
});
}
}
从一些 console.logs 中,每当我执行 handleSend 导致 setState 时,重新渲染并随后再次导致 componentDidUpdate 到 setState,重新渲染并第二次转到 componentDidUpdate并拒绝新的更新,直到此循环再次发生。
即使它现在正确显示,componentDidUpdate 也被点击了两次,而且我总是两次获取我的数据库查询和回调,这可能会给我带来额外的运行成本,而我不知道。我想知道是否有更好的编码实践来减少这种代码重复以及成本因素。
【问题讨论】:
标签: reactjs firebase callback event-handling react-lifecycle