Reactjs React钩子、React路由器和Userbase
我正在制作一个React网站,学习React钩子。在下面的项目中,Reactjs React钩子、React路由器和Userbase,reactjs,typescript,react-router,react-hooks,Reactjs,Typescript,React Router,React Hooks,我正在制作一个React网站,学习React钩子。在下面的项目中,header.tsx和home.tsx都是App.tsx中的组件。我有一个用户状态对象;i、 e.const[user,setUser]=useState()我加载到所有3个文件中(这是错误的吗?) 当我登录到home.tsx时,用户界面反映了变化-home.tsx中的条件体反映了user从未定义变为已定义的事实,并且显示了注销按钮 问题是:我希望header.tsx也能反映用户的变化;i、 e.我希望header.tsx能够“监
header.tsx
和home.tsx
都是App.tsx
中的组件。我有一个用户
状态对象;i、 e.const[user,setUser]=useState()代码>我加载到所有3个文件中(这是错误的吗?)
当我登录到home.tsx
时,用户界面反映了变化-home.tsx
中的条件体反映了user
从未定义变为已定义的事实,并且显示了注销按钮
问题是:我希望header.tsx
也能反映用户的变化;i、 e.我希望header.tsx
能够“监听”用户user
中的更改,并将其反映在UI上,但这并没有发生
有人能解释一下吗?我也不确定userbase.init()调用的位置
在某些背景下,这个项目是基于。我对它进行了修改,添加了React路由器
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;
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;
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;
header.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;
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;
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;
import React,{useffect,useState}来自“React”;
从“userbase js”导入{UserResult};
功能标题(道具:任意){
const[user]=useState();
返回(
用户名:{user?.Username}我肯定您注意到您为用户创建了两个useState,一个在App.tsx中,另一个在header.tsx中。这是主要问题。如果您想共享用户,请将用户作为道具从一个应用程序传递到另一个header,而不是创建另一个。工作解决方案:
App.tsx
:
import React, { useEffect, useState, ChangeEvent, FormEvent } from 'react';
import './App.css';
import {Switch, Route} from 'react-router-dom';
import Header from './components/header';
import Home from './components/home';
import Register from './components/register';
import Login from './components/login';
import userbase, { UserResult } from 'userbase-js';
function App() {
const [user, setUser] = useState<UserResult>();
const [toHome, setToHome] = useState<boolean>(false);
useEffect(() => {
userbase.init({ appId: process.env.REACT_APP_USERBASE_APP_ID as string })
.then(session => session.user && setUser(session.user))
}, []);
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)
setToHome(true);
}).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);
setToHome(true);
}).catch(err => alert(err));
}
}
return (
<div className="App">
<Header user={user}/>
<Switch>
<Route exact path='/'>
<Home user={user} setUser={setUser} />
</Route>
<Route exact path='/register'>
<Register
handleRegSubmit={handleRegSubmit}
regForm={regForm}
handleRegInputChange={handleRegInputChange}
toHome={toHome}
/>
</Route>
<Route exact path="/login">
<Login
handleLoginSubmit={handleLoginSubmit}
loginForm={loginForm}
handleLoginInputChange={handleLoginInputChange}
toHome={toHome}
/>
</Route>
</Switch>
</div>
);
}
export default App;
function Header(props: any) {
return (
<div>
<h1><a href="/">Project</a></h1>
{props.user ? (
<div>
Username: {props.user?.username}
</div>
) : (
<div>
Not logged in
</div>
)}
<hr/>
</div>
)
}
export default Header;
Register.tsx
:(Login.tsx
非常相似)
从'react router dom'导入{Redirect};
功能寄存器(道具:任意){
返回(
{props.toHome?:null}
登记
用户名:
密码:
)
}
导出默认寄存器;