我在登陆页面上有一个应用程序(App. tsx).在输入邮箱并单击"Let's get started"按钮后,应该将邮箱参数传播到Get Started页面并呈现GetStarted组件.现在,点击"Let's get started"按钮不会呈现任何新的内容/路由到新页面.我已经在整个流程中记录了 comments ,但我注意到唯一被记录的 comments 是App.tsx.这是我的逻辑:

当点击App.tsx中的"Let's get started"按钮时,会调用handleCreateProfileClick().在这个函数中,我调用了<GetStartedPage />组件,用户输入的邮箱作为参数.我有一个AppRouter. tsx文件处理应用程序的所有路由(包括GetStartedPage ofc).不应该调用GetStartedPage按钮点击渲染页面,因为AppRouter链接差异.每一页都有子弹吗下面提供了代码,为了简洁起见省略了不重要的逻辑.

这是我的App. tsx,它有一个按钮:

import React, { useState, useEffect, useRef, ReactNode } from 'react';
import signinIcon from 'icons/signin_icon.png';
import './App.css';
import GetStartedPage from './GetStartedPage';
import SignInPage from './SignInPage';

const App = () : ReactNode => {
  const [showSidePanel, setShowSidePanel] = useState(false);
  const [email, setEmail] = useState('');

  const handleEmailChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setEmail(event.target.value);
  };

  const  handleCreateProfileClick = () => {
    const emailInput = document.getElementById('email-input') as HTMLInputElement;
    const email = emailInput.value;

    if (!email) {
      alert('Please enter your email');
      return;
    }
    console.log("About to navigate from handleCreateProfile in App.tsx");
    return <GetStartedPage inputEmail={email} />
  };

  const handleSignInClick = () => {
    return <SignInPage />
  };

  const handleResize = () => {
    if (window.innerWidth > 600) {
      setShowSidePanel(false); // Hide the side panel if the screen size is greater than 600px
    }
  };

  useEffect(() => {
    window.addEventListener('resize', handleResize); // Add event listener for window resize
    return () => {
      window.removeEventListener('resize', handleResize); // Remove event listener on component unmount
    };
  }, []); // Empty dependency array ensures that the effect runs only once on component mount

  
  return (
      <div className="App">
      <div id="page-container">
      <div className="menu">
        <div className="menu-item sign-up" onClick={handleSignInClick}>
          <img src={signinIcon} alt="Sign in" className="signin"/>
          <span className="sign-up-text">Sign in</span>
        </div>
      </div>
      <div className="container">
        <div className="left-content">
      <div className="email-form">
        <input
          type="email"
          placeholder="Email address"
          onChange={handleEmailChange}
          value={email}
          id="email-input"
          required
        />
        <button className="lets-go-button" onClick={handleCreateProfileClick}>
          Let's get started
        </button>
      </div>
      <div className="sign-in">
        Already joined? <u><a href="/signin" onClick={handleSignInClick}>Sign in</a></u>.
      </div>
    </div>
    </div>
    </div>
    </div>
    );
};

export default App;

这是我的AppRouter. tsx:

import React, { useState } from 'react';
import { BrowserRouter as Router, Route, Routes, useNavigate, useLocation } from 'react-router-dom';
import App from './App';
import GetStartedPage from './GetStartedPage';

interface AppRouterProps {
  email: string;
}

const AppRouter: React.FC<AppRouterProps> = ({ email }) => {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<App />} />
        <Route path="/create-profile" element={<GetStartedPage inputEmail={email} />} />
        <Route path="/sign-in" element={<SignInPage />} />
      </Routes>
    </Router>
  );
};

export default AppRouter;

这是我的GetStarted. tsx页面:

import React, { useState, useEffect } from 'react';
import axios from 'axios';
interface GetStartedPageProps {
  inputEmail: string;
}

const GetStartedPage: React.FC<GetStartedPageProps> = (props) => {
  // More details here (omitted)
  console.log("Currently in Create profile page");
  // Updating the email state when the inputEmail prop changes, which we get from App.tsx
  useEffect(() => {
    setEmail(props.inputEmail);
  }, [props.inputEmail]);

    // More details here (omitted)
   
    try {
      await axios.post('/createProfile', userData);
      alert('Profile created successfully');
    } catch (error) {
      console.error('Error creating profile:', error);
      alert('Error creating profile');
    }
  };

  return (
    // More details here (omitted)
  );
};

export default GetStartedPage;

这是我的index.tsx:

import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import store from './redux/store';
import App from '../../frontend/src/App';

const container = document.getElementById('root');
if (container) {
  const root = createRoot(container);

  root.render(
    <Provider store={store}>
      {/* @ts-ignore */}
      <App>
      </App>
    </Provider>
  );
} else {
  console.error('Container element not found!');
}

推荐答案

从事件处理程序返回JSX并不是React组件呈现额外UI的方式.从代码和您的描述来看,您似乎应该将104路由到"/create-profile""/sign-in"路由来呈现GetStartedPageSignInPage组件.

为此,您应该导入并使用useNavigate钩子访问navigate函数,并向这些特定路由发出命令式导航操作.对于原始锚标记,您应该导入并呈现Link组件.

示例:

import { Link, useNavigate } from 'react-router-dom';

...

const App = () : ReactNode => {
  const navigate = useNavigate();

  const [showSidePanel, setShowSidePanel] = useState(false);
  const [email, setEmail] = useState('');

  const handleEmailChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setEmail(event.target.value);
  };

  const  handleCreateProfileClick = () => {
    const emailInput = document.getElementById('email-input') as HTMLInputElement;
    const email = emailInput.value;

    if (!email) {
      alert('Please enter your email');
      return;
    }
    
    return navigate("/create-profile"); // <-- navigate
  };

  const handleSignInClick = () => {
    return navigate("/sign-in"); // <-- navigate
  };

  ...

  
  return (
    <div className="App">
      <div id="page-container">
        <div className="menu">
          <div className="menu-item sign-up" onClick={handleSignInClick}>
            <img src={signinIcon} alt="Sign in" className="signin" />
            <span className="sign-up-text">Sign in</span>
          </div>
        </div>
        <div className="container">
          <div className="left-content">
            <div className="email-form">
              <input
                type="email"
                placeholder="Email address"
                onChange={handleEmailChange}
                value={email}
                id="email-input"
                required
              />
              <button
                type="button"
                className="lets-go-button"
                onClick={handleCreateProfileClick}
              >
                Let's get started
              </button>
            </div>
            <div className="sign-in">
              Already joined? <Link to="/signin"><u>Sign in</u></a>.
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default App;

Typescript相关问答推荐

相同端点具有不同响应时的RTKQuery类型定义

Angular 17 Select 错误core.mjs:6531错误错误:NG 05105:发现意外合成监听器@transformPanel.done

泛型和数组:为什么我最终使用了`泛型T []`而不是`泛型T []`?<><>

webpack错误:模块找不到.当使用我的其他库时,

如何通过TypeScript中的工厂函数将区分的联合映射到具体的类型(如类)?

打印脚本丢失函数的泛型上下文

当方法参数和返回类型不相互扩展时如何从类型脚本中的子类推断类型

无法从Chrome清除还原的初始状态数据

在TypeScrip的数组中判断模式类型

如何表示多层深度的泛型类型数组?

是否有一个版本的联合类型递归地使属性只出现在一个可选选项中?

从TypeScrip中的其他类型检索泛型类型

为什么特定的字符串不符合包括该字符串的枚举?

两个名称不同的相同打字界面-如何使其干燥/避免重复?

类型脚本中函数重载中的类型推断问题

TypeScript:如何使用泛型和子类型创建泛型默认函数?

如何提取具有索引签名的类型中定义的键

类型分布在第一个泛型上,但不分布在第二个泛型上

如何从联合类型推断函数参数?

我可以使用对象属性的名称作为对象中的字符串值吗?