【问题标题】:How Can I Update A React Component From a Separate Sibling Component in a Separate File?如何从单独文件中的单独同级组件更新 React 组件?
【发布时间】:2023-01-03 10:24:59
【问题描述】:

我正在尝试让我的导航栏更新以在用户尝试登录并成功后显示登录信息。这是相关的代码文件:

应用程序.js

class App extends Component {
  render(){
    return (
      <div>
        <div className="App">
          <header className="App-header">
            <NavBar />
            <Main />
          </header>
        </div>
      </div>
    );
  }
}

export default App;

导航栏.js

const NavBar = () => {
  const [userInfo, SetUserInfo] = useState();

  useEffect(() => {
    SetNavBar(null);
  }, [])

  function SetNavBar(element){
    var user = auth.currentUser;
    console.log(auth.currentUser);

    if (user){
      var userInfo = 
        React.createElement('div', {id : 'userDiv'},
          React.createElement('span', {id : 'userDisplayName'}, user.email),
          React.createElement('span', {id : 'signoutSpan'}, 
            '(', 
            React.createElement('button', {id : 'signoutButton', onClick : (e) => SignOutUser(e.target)}, 'Signout'),
            ')'
          )
        );
      SetUserInfo(userInfo);
    }
    else if(element != null && element.nodeName === 'A'){
      var urlTO = element.href;
        
      if(!urlTO.includes("login") && !urlTO.includes("signup")){
        var userLoginSignupElement = 
          React.createElement('span', {id : 'loginSignupOptions'}, 
            React.createElement(Link, {to : '/login', onClick : (e) => SetNavBar(e.target)}, 'Login'), 
            '/',
            React.createElement(Link, {to : '/signup', onClick : (e) => SetNavBar(e.target)}, 'Signup')
          );
      }
      else{
        var userLoginSignupElement = null;
      }
      SetUserInfo(userLoginSignupElement);
    }
    else{
      var userLoginSignupElement = 
        React.createElement('span', {id : 'loginSignupOptions'}, 
          React.createElement(Link, {to : '/login', onClick : (e) => SetNavBar(e.target)}, 'Login'), 
          '/',
          React.createElement(Link, {to : '/signup', onClick : (e) => SetNavBar(e.target)}, 'Signup')
        );
      SetUserInfo(userLoginSignupElement);
    }
  }

  async function SignOutUser(element){
    try{
      await signOut(auth);
      SetNavBar(null)
    }
    catch(err){
      console.log(err);
    }
  }

  return (
    <div>
      <nav id='navBar'>
        <div id='logoTitleDiv'>
          <img id='navBarLogo' src={logo} alt='Skeeters logo.'></img>
          <Link to='/' onClick={e => SetNavBar(e.target)}>
            <h2 id='pageHeader'>DJSkeeterB</h2>
          </Link>
        </div>
        {userInfo}
      </nav>
    </div>
  );
}

export default NavBar;

主.js

const Main = () => {
    return (
        <div id='main'>
            <Routes>
                <Route exact path='/' element={<SongRequests/>}/>
                <Route exact path='/upcoming' element={<Upcoming/>}/>
                <Route exact path='/signup' element={<Signup/>}/>
                <Route exact path='/login' element={<Login/>}/>
            </Routes>
        </div>
    );
}

export default Main;

登录.js

const Login = () => {
  const [navigateToHome, SetNavigateToHome] = useState(false);
  const [userEmail, SetUserEmail] = useState('');
  const [userPassword, SetUserPassword] = useState('');

  const userEmailRef = useRef('');
  userEmailRef.current = userEmail;

  const userPasswordRef = useRef('');
  userPasswordRef.current = userPassword;

  const LoginToFirebase = async () => {
    try {
      await signInWithEmailAndPassword(auth, userEmailRef.current, userPasswordRef.current);
      console.log(auth.currentUser);
      document.getElementById('emailInput').innerHTML = '';
      document.getElementById('passwordInput').innerHTML = '';

      SetUserEmail('');
      SetUserPassword('');

      SetNavigateToHome(true);
    } catch (err) {
      console.error(err);
    }
  };

  if(navigateToHome === true){
    return <Navigate to='/'/>;
  }
  return (
      <div id='loginDiv'>
        <div>
          <h2>Login</h2>
        </div>
        <div>
          <label>Email: </label>
          <input id='emailInput' type='email' placeholder='example@gmail.com' onChange={e => SetUserEmail(e.target.value)}/>
        </div>
        <div>
          <label>Password: </label>
          <input id='passwordInput' type='password' placeholder='Password' onChange={e => SetUserPassword(e.target.value)}/>
        </div>
        <button onClick={e => LoginToFirebase()}>Submit</button>
        <div>
          <span id='alreadySignedUpSpan'>
            <Link to='/signup'>Not registered? Signup here</Link>
          </span>
        </div>
      </div>
  );
}

export default Login;

本质上,我让我的应用程序始终显示导航栏,并且根据页面或用户身份验证,它会更新为不同。 Main 组件目前正在使用 react-router-dom 链接几个页面。用户在Login.jsSignup.js 上登录或注册后,他们将被重定向到主页。他们使用 firebase 身份验证成功登录。重定向后,他们登陆主页,但导航栏没有更新,因为我不知道如何调用 Login.js 中发生的状态更改以影响 NavBar.js

导航栏无法知道这似乎是成功的身份验证。我尝试将authauth.currentUser 视为状态,以查看它们在更新时是否可以以useEffect(() =&gt; {}, [auth]) 的方式用于调用NavBar.js 中的SetNavBar 函数。

如何在我的LoginToFirebase()函数结束时更新我的​​组件NavBar

【问题讨论】:

    标签: reactjs firebase react-hooks firebase-authentication web-component


    【解决方案1】:

    通过将 userEmail 状态提升到您的 App 组件(可能还有所有登录功能)并使您的 Login 组件接受 onClickLogin 的支持。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 2016-02-07
      • 2015-04-21
      • 2021-06-05
      • 1970-01-01
      • 2021-09-15
      相关资源
      最近更新 更多