Reactjs React钩子、React路由器和Userbase

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能够“监

我正在制作一个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
能够“监听”用户
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}
登记
用户名:
密码:
)
}
导出默认寄存器;