我正在尝试在 React Js 中创建一个登录和注册页面,其想法是它们应该呈现在同一页面上,并且用户应该能够在它们之间切换(类似于这个例子:https:// /codepen.io/guycode/pen/VwaKVrb)
我创建了一个切换功能,并且可以在两种模式之间切换,但问题是当我切换到注册模式时,网址仍然是“/Login”,另一个大问题是页面的样式和前端设计停止工作它应该虽然当牵引模式注册和登录是分开的而没有切换模式时,样式效果很好
import UserServices from '../Services/service';
import img1 from '../pages/students.png';
import img2 from '../pages/students2.png';
import React, { useState } from "react";
import toast, {Toaster} from 'react-hot-toast';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {faCircleExclamation} from '@fortawesome/free-solid-svg-icons';
const Signup = () => {
const [firstName , setfirstName] = useState('')
const [lastName , setlastName] = useState('')
const [birthday , setbirthday] = useState('')
const [password , setpassword] = useState('')
const [email , setemail] = useState('')
const [errors , setErrors] = useState(
{
firstName : '',
lastName : '',
email : '',
password : '',
birthday : '',
});
const formValidation = () =>{
const pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&])[A-Za-z0-9@$!%*?&]{8,}$/;
let localErrors = {...errors}
if(firstName === ""){
localErrors.firstName = 'First name required';
}
if(lastName === ""){
localErrors.lastName = 'Last name required';
}
if(email === ""){
localErrors.email = 'Email required';
}
if ((password === "") || (!pattern.test(password))){
localErrors.password = 'Password required';
}
if(birthday === ""){
localErrors.birthday = 'date required';
}
setErrors(localErrors);
console.log(localErrors);
const isValid = Object.values(localErrors).every(error => error === '');
return isValid;
}
const signUp = async (e) =>{
e.preventDefault();
if (formValidation()){
const data = {
firstName : firstName,
lastName : lastName,
email : email,
password : password,
birthday : birthday,
}
try {
const response = await UserServices.signup(data)
console.log("response ====>", response);
toast.success('Successfully created!');
setfirstName('');
setlastName('');
setemail('');
setpassword('');
setbirthday('');
}catch(err){
console.log(err)
toast.success('Successfully created!');
}
}else{
console.log("form invalid");
}
}
return (
<div class="container">
<div class="forms-container">
<Toaster />
<div class="signin-signup">
<form action="#" class="sign-up-form" onSubmit={signUp}>
<h2 class="title">Sign up</h2>
<div class="input-field">
<i class="fas fa-user"></i>
<input type="text" placeholder="First Name" value={firstName} onChange={ (e)=>setfirstName(e.target.value)}/>
{errors.firstName !== '' && (
<div className="error-message">
<FontAwesomeIcon icon={faCircleExclamation} />
{errors.firstName}
</div>
)}
</div>
<div class="input-field">
<i class="fas fa-user"></i>
<input type="text" placeholder="Last Name" value={lastName} onChange={ (e)=>setlastName(e.target.value)}/>
{errors.lastName !== '' && (
<div className="error-message">
<FontAwesomeIcon icon={faCircleExclamation} />
{errors.lastName}
</div>
)}
</div>
<div class="input-field">
<i class="fas fa-envelope"></i>
<input type="email" placeholder="Email" value={email} onChange={ (e)=>setemail(e.target.value)} />
{errors.email !== '' && (
<div className="error-message">
<FontAwesomeIcon icon={faCircleExclamation} />
{errors.email}
</div>
)}
</div>
<div class="input-field">
<i class="fas fa-lock"></i>
<input type="password" placeholder="Password" value={password} onChange={ (e)=>setpassword(e.target.value)} />
{errors.password !== '' && (
<div className="error-message">
<FontAwesomeIcon icon={faCircleExclamation} />
{errors.password}
</div>
)}
</div>
<div class="input-field">
<i class="fas fa-user"></i>
<input type="date" placeholder="Date_of_Birth" value={birthday} onChange={ (e)=>setbirthday(e.target.value)}/>
{errors.birthday !== '' && (
<div className="error-message">
<FontAwesomeIcon icon={faCircleExclamation} />
{errors.birthday}
</div>
)}
</div>
<input type="submit" class="btn" value="Sign up" />
</form>
</div>
</div>
<div class="panels-container">
<div class="panel left-panel">
<div class="content">
<h3>New in our faClub ?</h3>
<p>Enter your personal details and start journey with us.</p>
<button class="btn transparent" id="sign-up-btn">Sign up</button>
</div>
<img src={img1} class="image" alt="" />
</div>
<div class="panel right-panel">
<div class="content">
<h3>One of our faClub ?</h3>
<p>To keep connected with us please login with your personal info.</p>
<button class="btn transparent" id="sign-in-btn">Sign in</button>
</div>
<img src={img2} class="image" alt="" />
</div>
</div>
</div>
)
}
export default Signup
import UserServices from '../Services/service';
import img1 from '../pages/students.png';
import img2 from '../pages/students2.png';
import React, { useState } from "react";
import toast, {Toaster} from 'react-hot-toast';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {faCircleExclamation} from '@fortawesome/free-solid-svg-icons';
const SignIn = () => {
const [password , setpassword] = useState('')
const [email , setemail] = useState('')
const [errors , setErrors] = useState(
{
email : '',
password : '',
});
const formValidation = () =>{
const pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&])[A-Za-z0-9@$!%*?&]{8,}$/;
let localErrors = {...errors}
if(email === ""){
localErrors.email = 'Email required';
}
if ((password === "") || (!pattern.test(password))){
localErrors.password = 'Password required';
}
setErrors(localErrors);
const isValid = Object.values(localErrors).every(error => error === '');
return isValid;
}
const signin = async (e) =>{
e.preventDefault();
console.log("forme submitted");
if (formValidation()){
const data = {
email : email,
password : password,
}
try {
const response = await UserServices.signin(data)
console.log("response ====>", response);
toast.success('Successfully Loget in!');
setemail('');
setpassword('');
}catch(err){
console.log(err)
toast.success('Successfully created!');
}
}else{
console.log("forme invalid")
}
}
return (
<div class="container">
<div class="forms-container">
<Toaster />
<div class="signin-signup">
<form action="#" class="sign-in-form" onSubmit={signin}>
<h2 class="title">Sign in</h2>
<div class="input-field">
<i class="fas fa-user"></i>
<input type="text" placeholder="Email" value={email} onChange={ (e)=>setemail(e.target.value)}/>
{errors.email !== '' && (
<div className="error-message">
<FontAwesomeIcon icon={faCircleExclamation} />
{errors.email}
</div>
)}
</div>
<div class="input-field">
<i class="fas fa-lock"></i>
<input type="password" placeholder="Password" value={password} onChange={ (e)=>setpassword(e.target.value)} />
{errors.password !== '' && (
<div className="error-message">
<FontAwesomeIcon icon={faCircleExclamation} />
{errors.password}
</div>
)}
</div>
<input type="submit" value="Login" class="btn solid" />
</form>
</div>
</div>
<div class="panels-container">
<div class="panel left-panel">
<div class="content">
<h3>New in our faClub ?</h3>
<p>Enter your personal details and start journey with us.</p>
<button class="btn transparent" id="sign-up-btn">Sign up</button>
</div>
<img src={img1} class="image" alt="" />
</div>
<div class="panel right-panel">
<div class="content">
<h3>One of our faClub ?</h3>
<p>To keep connected with us please login with your personal info.</p>
<button class="btn transparent" id="sign-in-btn">Sign in</button>
</div>
<img src={img2} class="image" alt="" />
</div>
</div>
</div>
)
}
export default SignIn;
import './App.css';
import Signup from './pages/signup.js';
import SignIn from './pages/login.js';
import img1 from '../src/pages/students.png';
import img2 from '../src/pages/students2.png';
import { useState } from 'react';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
function App() {
const [isSignUpMode, setIsSignUpMode] = useState(false);
const toggleMode = () => {
setIsSignUpMode(prevMode => !prevMode);
};
return (
<div className={`container ${isSignUpMode ? 'sign-up-mode' : ''}`}>
<div className="forms-container">
{isSignUpMode ? <Signup /> : <SignIn />}
</div>
<div className="panels-container">
<div className="panel left-panel">
<div className="content">
<h3>New in our faClub ?</h3>
<p>Enter your personal details and start journey with us.</p>
<button className="btn transparent" onClick={toggleMode}>Sign up</button>
</div>
<img src={img1} className="image" alt="" />
</div>
<div className="panel right-panel">
<div className="content">
<h3>One of our faClub ?</h3>
<p>To keep connected with us please login with your personal info.</p>
<button className="btn transparent" onClick={toggleMode}>Sign in</button>
</div>
<img src={img2} className="image" alt="" />
</div>
</div>
</div>
)}
export default App;
import express from 'express';
import { signup } from '../controllers/user.controller.js';
import { signin } from '../controllers/user.controller.js';
const router = express.Router();
router.post('/signup' ,signup );
router.post('/login',signin);
export {router};
App.css没有问题
这是在react中使用Outlet的常见情况,Outlet用在父路由元素中,然后可以在父路由的路由内渲染2个子路由元素,首先你将这样设置你的路由器
我认为你可以做这样的事情来定义你的路由,这样 /login 和 /signup 通过一个身份验证出口,这样你就可以在两者之间切换,并且路由会改变
// * index.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import Login from "./login";
import SignUp from "./signup";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
const router = createBrowserRouter([
{
path: "auth",
element: <App />,
children: [
{
path: "login",
element: <Login />,
},
{
path: "signup",
element: <SignUp />,
},
],
},
]);
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>,
);
// * App.jsx
import { Outlet } from "react-router-dom";
import "./App.css";
export default function App() {
return (
<div className="App">
This is app route and this is app
<Outlet />
</div>
);
}
// * login.jsx
import React from "react";
import { Link } from "react-router-dom";
const Login = () => {
return (
<>
<h1>Login Page</h1>
<p>
Already have an account? <Link to="/signup">Sign Up</Link>
</p>
</>
);
};
export default Login;
// * signup.jsx
import React from "react";
import { Link } from "react-router-dom";
const SignUp = () => {
return (
<>
<h1>Sign Up Page</h1>
<button><Link to="/login">Go to Login</Link></button>
</>
);
};
export default SignUp;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
以这种方式处理它,您可以将注册和登录的样式分开,这可能会解决问题,甚至可以解决/登录部分。 您的应用程序将有两条不同的路线 /login 和 /signup,嗨