这是我第一次使用useEffect钩子。它所做的是读取数据库,看看是否有一个值返回,如果一个值返回的是userToken,它是一个帐户的标志,所以它登录你。然而,我有两个问题。链接名称按钮不会自动让你登录,你必须在之后的输入框中输入另一个字母才能登录。我试图通过在第49行writeUserData下添加connectUser来修复这个问题,但这只是使网站崩溃。我的第二个问题是登录后我不能在页面上显示{userToken}。我收到错误:对象作为React子对象无效(发现:带有键{username}的对象)。如果您打算呈现子元素的集合,请使用数组。
import React, { useState, useEffect } from "react";
import {initializeApp} from 'firebase/app';
import { getDatabase, ref, set, child, get} from 'firebase/database';
export default function Username(props) {
const [userName, setUsername] = useState('');
const [userToken, setuserToken] = useState('')
const clientCredentials = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
}
const app = initializeApp(clientCredentials);
const db = getDatabase();
const address = props.address;
function writeUserData(userId, userN, ) {
const reference = ref(db, 'users/' + userId);
set(reference, {
username: userN,
});
}
const dbRef = ref(getDatabase());
function connectUser() {
get(child(dbRef, `users/${address}`)).then((snapshot) => {
if (snapshot.exists()) {
setuserToken(snapshot.val());
} else {
console.log("No data available");
}
}).catch((error) => {
console.error(error);
});
}
const handleChange = (event) => setUsername(event.target.value);
function handleClick(e) {
writeUserData( address, userName);
}
useEffect(() => {
connectUser()
});
while (userToken == '')
return (
<>
<div>
<p className = "account-Info" >address: {address}</p>
</div>
<div id="form">
<h2 className='user-Create' > Username </h2>
<form id='set-User'>
<input id='username' className="user-Create" type='text' value={userName} onChange={handleChange}
required minLength='3' maxLength='30' pattern="[a-zA-Z0-9_]+" title='only letters, numbers, and underscores.'/>
<button className='user-Create' type="button" onClick={handleClick}>Link Name</button>
</form>
</div>
</>
);
while (userToken)
return (
<p className = "account-Info" >hi user</p>
);
}
首先,请不要使用while
。请使用if
。
if (!Boolean(userToken)) return <something />;
// No need to give condition here
// If userToken is not false, this will return
return <main />;
第二,useEffect的依赖项,根据你写的,它是
useEffect(() => {
connectUser();
});
这意味着每次组件更新时都执行connectUser()
。传递依赖项。如果不需要依赖,使用[]
,这意味着在组件挂载时只执行一次connectUser()
。
useEffect(() => {
connectUser();
},[]);
第三,对于Error: Objects are not valid as a React child (found: object with keys {username})
,如果将来遇到类似的错误,请使用console.log()
进行调试。在您的情况下,console.log(userToken)
并在浏览器的控制台中查看。
第四,如果您正在处理身份验证,您是否考虑使用firebase/auth
?
对于多次运行的useEffect,请传入一个依赖数组。查看useEffect上的react文档。您可以首先将一个空数组作为useEffect
的第二个参数