【发布时间】:2021-09-12 16:11:09
【问题描述】:
所以我的项目是一个 reactjs 网络应用程序,它将其数据存储在一个 firestore 实时数据库中。本来所有的组件都是基于类的,但是我把它全部重构为函数式组件,这时候我遇到了标题中提到的错误。
Uncaught TypeError: Cannot read property 'displayName' of undefined
at Chat (Chat.js:61)
at renderWithHooks (react-dom.development.js:14985)
at updateFunctionComponent (react-dom.development.js:17356)
at beginWork (react-dom.development.js:19063)
at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
at invokeGuardedCallback (react-dom.development.js:4056)
at beginWork$1 (react-dom.development.js:23964)
at performUnitOfWork (react-dom.development.js:22776)
at workLoopSync (react-dom.development.js:22707)
at renderRootSync (react-dom.development.js:22670)
at performSyncWorkOnRoot (react-dom.development.js:22293)
at react-dom.development.js:11327
at unstable_runWithPriority (scheduler.development.js:468)
at runWithPriority$1 (react-dom.development.js:11276)
at flushSyncCallbackQueueImpl (react-dom.development.js:11322)
at flushSyncCallbackQueue (react-dom.development.js:11309)
at flushPassiveEffectsImpl (react-dom.development.js:23620)
at unstable_runWithPriority (scheduler.development.js:468)
at runWithPriority$1 (react-dom.development.js:11276)
at flushPassiveEffects (react-dom.development.js:23447)
at react-dom.development.js:23324
at workLoop (scheduler.development.js:417)
at flushWork (scheduler.development.js:390)
at MessagePort.performWorkUntilDeadline (scheduler.development.js:157)
该错误是针对我的代码中的这一行的:
Header />
59 | </div>
60 | <div className="user-info">
> 61 | Logged in as: <strong id="user-tag">{state.user.displayName}</strong>
| ^ 62 | </div>
63 | {console.log("the log: " + state.user.displayName)}
64 | <div className="chatbox">
我也收到此错误:
index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at Chat (http://localhost:3000/static/js/main.chunk.js:804:83)
at Route (http://localhost:3000/static/js/vendors~main.chunk.js:114703:29)
at PrivateRoute (http://localhost:3000/static/js/main.chunk.js:38:14)
at Switch (http://localhost:3000/static/js/vendors~main.chunk.js:114905:29)
at Router (http://localhost:3000/static/js/vendors~main.chunk.js:114338:30)
at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:113958:35)
at App (http://localhost:3000/static/js/main.chunk.js:99:83)
console.<computed> @ index.js:1
import React, { useState, useEffect } from "react";
import { auth } from "../services/firebase";
import { db } from "../services/firebase";
import Header from "../components/Header";
import { writeChats } from "../helpers/db";
function Chat() {
const [state, setState] = useState({
user: auth().currentUser,
chats: [],
content: "",
readError: null,
writeError: null,
});
useEffect(() => {
setState({ readError: null });
console.log("read error set to null now attempting to fetch data");
try {
db.ref("messages").on("value", (snapshot) => {
let chats = [];
snapshot.forEach((snap) => {
chats.push(snap.val());
});
setState({ chats });
});
} catch (err) {
this.setState({ readError: err.message });
}
console.log("data fetched");
}, []);
function handleChange(event) {
setState({
content: event.target.value,
});
}
async function handleSubmit(event) {
event.preventDefault();
setState({ writeError: null });
try {
await writeChats({
name: state.user.displayName,
content: state.content,
timestamp: Date.now(),
uid: state.user.uid,
});
setState({ content: "" });
} catch (error) {
setState({ writeError: error.message });
}
}
return (
<div className="chatter">
<div className="header">
<Header />
</div>
<div className="user-info">
Logged in as: <strong id="user-tag">{state.user.displayName}</strong>
</div>
{console.log("the log: " + state.user.displayName)}
<div className="chatbox">
<div className="chats">
{state.chats.map((chat) => {
return (
<p key={chat.timestamp} style={{ fontSize: "1.2rem" }}>
{chat.content}
<code style={{ fontSize: "0.5rem" }}> {chat.name}</code>
</p>
);
})}
</div>
<div className="input-group">
<form className="textbar" onSubmit={handleSubmit}>
<input
style={{ borderRadius: "10px" }}
size="50"
onChange={handleChange}
value={state.content}
></input>
{state.error ? <p>{state.writeError}</p> : null}
<button className="send-btn" type="submit">
Send
</button>
</form>
</div>
</div>
</div>
);
}
export default Chat;
这可能是一些基本错误,但我不知道该怎么做,请多多包涵。
我的一个猜测是,state.user.displayName 这行可能是指我的状态的旧版本,我使用useState() 钩子创建它,因为我读到状态中的每个更新都会重新渲染整个组件,所以也许我需要使用上下文,但我不确定,所以请帮助我,如果您需要任何详细信息,请告诉我。
编辑说明:我已经发布了这个错误的完整代码,请让我知道我在这里犯了哪些其他错误,比如我违反了任何编码习惯或任何其他严重错误。啊,我知道那些内联 css 语句很糟糕,对此感到抱歉。
【问题讨论】:
-
你如何更新
state? -
使用状态初始化返回的 setState() 函数
-
我应该发布整个代码吗?我的意思是一个文件
-
@AnandThevar 请做
-
请在设置用户状态的地方添加相关代码。
标签: reactjs firebase firebase-authentication react-hooks