【发布时间】:2021-07-14 04:35:09
【问题描述】:
我正在开发一个 React 网站并学习 React Hooks。在下面的项目中,header.tsx 和home.tsx 都是App.tsx 内部的组件。我有一个user 状态对象;即我在所有 3 个文件中加载的 const [user, setUser] = useState<UserResult>();(这是错误的吗?)。
当我在home.tsx 中登录userbase 时,UI 反映了这种变化——home.tsx 中的条件主体反映了user 从未定义到已定义的事实,并显示了注销按钮。
问题来了:我希望header.tsx 也能反映user 的变化;即我希望 header.tsx 能够“监听”user 的变化并将它们反映在 UI 上,但它不会发生。
谁能解释一下?我也不确定userbase.init() 呼叫的位置。
对于某些背景,此项目基于this tutorial。我对其进行了修改以添加 React Router。
App.tsx
import React, { useEffect, useState } from 'react';
import './App.css';
import {Switch, Route} from 'react-router-dom';
import Header from './components/header';
import Home from './components/home';
import userbase, {UserResult} from 'userbase-js';
function App() {
const [user,setUser] = useState<UserResult>();
useEffect(() => {
userbase.init({ appId: process.env.REACT_APP_USERBASE_APP_ID as string })
.then(session => session.user && setUser(session.user))
}, []);
return (
<div className="App">
<Header />
<Switch>
<Route exact path='/' component={Home} />
</Switch>
</div>
);
}
export default App;
home.tsx
import React, { ChangeEvent, FormEvent, useEffect, useState } from 'react';
import userbase, { UserResult } from 'userbase-js';
function Home() {
const [user, setUser] = useState<UserResult>();
const [regForm, setRegForm] = useState<{
username?: string,
password?: string
}>({ username: '', password: '' });
const handleRegInputChange = (event: ChangeEvent<HTMLInputElement>) =>
setRegForm({ ...regForm, [event.target.name]: event.target.value });
const handleRegSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (regForm.username && regForm.password) {
userbase.signUp({
username: regForm.username,
password: regForm.password,
rememberMe: 'session'
}).then((ur: UserResult) => setUser(ur))
.catch(err => alert(err));
}
}
const [loginForm, setLoginForm] = useState<{
username?: string,
password?: string
}>({ username: '', password: '' });
const handleLoginInputChange = (event: ChangeEvent<HTMLInputElement>) =>
setLoginForm({ ...loginForm, [event.target.name]: event.target.value });
const handleLoginSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (loginForm.username && loginForm.password) {
userbase.signIn({
username: loginForm.username,
password: loginForm.password,
rememberMe: 'session'
}).then((ur: UserResult) => setUser(ur))
.catch(err => alert(err));
}
}
const handleLogout = () => {
userbase.signOut().then(() => setUser(undefined))
.catch(err => alert(err));
}
return (
<div>
<h2>Homepage</h2>
<a href="/robertbrennan">Show example profile</a>
<br/>
{user ? (
<div>
<div>
Signed in as {user.username}.{' '}
<button onClick={handleLogout}>Log out</button>
</div>
</div>
) : (
<div>
<h3>Register</h3>
<form onSubmit={handleRegSubmit}>
<label>
Username:
<input type="text" name="username" value={regForm?.username} onChange={handleRegInputChange} />
</label>
<label>
Password:
<input type="password" name="password" value={regForm?.password} onChange={handleRegInputChange} />
</label>
<input type="submit" value="Submit" />
</form>
<br/><br/><hr/><br/>
<h3>Log in</h3>
<form onSubmit={handleLoginSubmit}>
<label>
Username:
<input type="text" name="username"
value={loginForm?.username} onChange={handleLoginInputChange} />
</label>
<label>
Password:
<input type="password" name="password"
value={loginForm?.password} onChange={handleLoginInputChange} />
</label>
<input type="submit" value="Submit" />
</form>
</div>
)}
</div>
)
}
export default Home;
header.tsx
import React, { useEffect, useState } from 'react';
import { UserResult } from 'userbase-js';
function Header(props: any) {
const [user] = useState<UserResult>();
return (
<div>
<h1><a href="/">Project</a></h1>
Username: {user?.username} <---- THIS DOESN'T CHANGE!
<hr/>
</div>
)
}
export default Header;
【问题讨论】:
标签: reactjs typescript react-router react-hooks