I have an application on the landing page (App.tsx). After inputting your email and clicking a "Let's get started" button, it is supposed to propagate the email parameter to the Get Started page and render the GetStarted component. Right now, clicking the "Let's get started" button does not render anything new/route to the new page. I've logged comments throughout my flow, but I noticed the only comment that gets logged is in App.tsx. This is my logic:
When clicking the button "Let's get started" in App.tsx, this calls the handleCreateProfileClick(). Inside this function, I call the <GetStartedPage /> component, with the email the user types in as the parameter. I have an AppRouter.tsx file that handles all routing for the application (including GetStartedPage ofc). Shouldn't calling the GetStartedPage on a button click render the page, since AppRouter links the diff. slugs to each page? Provided code below and omitted unimportant logic for conciseness.
This is my App.tsx, which has the button:
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;
This is my 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;
This is my GetStarted.tsx page:
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;
This is my 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!');
}
Returning JSX from event handlers isn't how React components render additional UI. From the code and your description it seems like you should navigate to the
"/create-profile"and"/sign-in"routes to render theGetStartedPageandSignInPagecomponents.For this you should import and use the
useNavigatehook to access thenavigatefunction and issue imperative navigation actions to these specific routes. For the raw anchor tag you should import and render theLinkcomponent.Example: