I have two forms.
Login.jsx:
import React, {Fragment, useState } from "react";
import axios from "axios";
export const Login = (props) => {
const [user, setUser] = useState('');
const [pass, setPass] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
const data = {
KorisnickoIme: user,
Lozinka: pass
};
const url ='https://localhost:44357/api/Fin/Login';
axios.post(url, data).then((result)=>{
alert(result.data);
}).catch((error)=>{
alert(error);
})
};
return (
<Fragment>
<div className="auth-form-container">
<h2>Пријава</h2>
<form className="login-form" onSubmit={handleSubmit}>
<label htmlFor="user">Корисничко ме</label>
<input value ={user} onChange ={(e) => setUser(e.target.value)}placeholder="korisnicko_ime" id="user" name="user" required/>
<label htmlFor="email">Лозинка</label>
<input
value={pass}
onChange={(e) => setPass(e.target.value)}
type="password"
placeholder="********"
></input>
<button type="submit">Пријави се</button>
</form>
<button
className="link-btn"
onClick={() => props.onFormSwitch("register")}
>
Немаш налог? Региструј се овде.
</button>
</div>
</Fragment>
);
};
and Register.jxs:
import React, {Fragment, useState} from "react";
import axios from "axios";
import { ProfileSetUp } from './ProfileSetUp';
export const Register = (props) => {
const [email, setEmail] = useState('');
const [pass, setPass] = useState('');
const [name, setName] = useState('');
const [user, setUser] = useState('');
const [lastname, setLastname] = useState('');
const [checkPass, setCheckPass] = useState('');
const handleSubmit = (e) => {
if(pass==checkPass){
e.preventDefault();
const data = {
KorisnickoIme:user,
Ime: name,
Prezime: lastname,
Email: email,
Lozinka: pass
};
const url ='https://localhost:44357/api/Fin/Registration';
axios.post(url, data).then((result)=>{
alert(result.data);
}).catch((error)=>{
alert(error);
})
}else{
alert("Лозинке се не поклапају");
}
}
return(
<Fragment>
<div className="auth-form-container">
<h2>Регистрација</h2>
<form className="reg-form" onSubmit={handleSubmit}>
<label htmlFor="name">Име</label>
<input value ={name} onChange ={(e) => setName(e.target.value)}placeholder="Унесите Ваше име" id="name" name="name" required/>
<label htmlFor="lastname">Презиме</label>
<input value ={lastname} onChange ={(e) => setLastname(e.target.value)}placeholder="Унесите Ваше презиме" id="lastname" name="lastname" required/>
<label htmlFor="email">Е-маил</label>
<input value ={email} onChange ={(e) => setEmail(e.target.value)}type="email" placeholder="vasmail#fink.com" id="email" name="email" required/>
<label htmlFor="user">Корисничко ме</label>
<input value ={user} onChange ={(e) => setUser(e.target.value)}placeholder="Унесите Ваше korisnicko_ime" id="user" name="user" required/>
<label htmlFor="password">Лозинка</label>
<input value ={pass} onChange ={(e) => setPass(e.target.value)}type="password" placeholder="********" id="password" name="password" required/>
<label htmlFor="checkPass">Потврдите лозинку</label>
<input value ={checkPass} onChange ={(e) => setCheckPass(e.target.value)}type="password" placeholder="********" id="checkPass" name="checkPass" required/>
<button type="submit">Региструј се</button>
</form>
<button className="link-btn" onClick={() => props.onFormSwitch('login')}>Имате налог? Пријавите се.</button>
</div>
</Fragment>
)
}
/* */
After registering I want to send user to Login form but I am not sure how should I do it. Here is App.js just in case:
import React, {useState} from 'react';
import './App.css';
import { Register } from './Register';
import { Login } from './Login';
import { ProfileSetUp } from './ProfileSetUp';
function App() {
const [currentForm, setCurrentForm] = useState('login');
const toggleForm = (formName) => {
setCurrentForm(formName);
}
return (
<div className="App">
{
currentForm === "login" ? <Login onFormSwitch={toggleForm} /> : <Register onFormSwitch={toggleForm} />
}
</div>
);
}
export default App;
I am not sure how React page is represented so I am not sure how to use window.open() etc.
I followed one tutorial where is shown how to make this toggle switch function, which I like but I think that will make me troubles with other pages.
You can use the react-router package to link between different pages and pass data. Here is the documentation for the package https://reactrouter.com/en/main.
If you don't want to navigate to different components using routing, you could just use state variables to show/hide components included in a single parent component.
Related
I'm trying to fetch the uid and token through the URL pathname using match in my React app. But I got error:
Uncaught TypeError: n is undefined
and this is my code snippet:
const ResetPasswordConfirm = ( {match, reset_password_confirm} ) => {
...
const onSubmit = e=> {
e.preventDefault();
const uid = match.params.uid;
const token = match.params.token;
reset_password_confirm(uid, token, new_password, re_new_password);
setRequestSent(true);
};
};
According to this thread: https://stackoverflow.com/questions/70609785/uncaught-typeerror-match-is-undefined#:~:text=react%2Drouter%2Ddom%20v5,render%20or%20children%20prop%20functions.
It says it might have something to do with the version of react router, so I tried to use useParams(), but I found it hard to implement it...
I also tried to use matchPath, but I can find few examples.
Can anybody help me with this issue please?
Update:
react-router-dom version: 6.8.0
ResetPasswordConfirm is running in my container package.
import React, { useState } from "react";
import { Navigate, useParams } from 'react-router-dom';
import { connect } from 'react-redux';
import { reset_password_confirm } from '../actions/auth';
const ResetPasswordConfirm = ( {match, reset_password_confirm} ) => {
const [requestSent, setRequestSent] = useState(false);
const [formData, setFormData] = useState({
new_password: '',
re_new_password: ''
});
const { new_password, re_new_password } = formData;
const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = e=> {
e.preventDefault();
const uid = match.params.uid;
const token = match.params.token;
reset_password_confirm(uid, token, new_password, re_new_password);
setRequestSent(true);
};
// Is the user sending the request?
// Redirect them to the home page
if (requestSent) {
return <Navigate to='/'/>
}
return (
<div className="container mt-5">
<form onSubmit={e => onSubmit(e)}>
{/* <div className="form-group">
<input className="form-control" type="email" placeholder="Email" name="email" value={email} onChange={e => onChange(e)} required></input>
</div>
<div className="form-group">
<input className="form-control" type="password" placeholder="Password" name="password" value={password} onChange={e => onChange(e)} minLength='6' required></input>
</div>
<button className="btn btn-primary" type="submit">Login</button> */}
<div className="form-group">
<label htmlFor="exampleInputPassword1">Password</label>
<input
type="password"
className="form-control"
id="exampleInputPassword1"
placeholder="New Password"
name="new_password"
value={new_password}
onChange={e => onChange(e)}
minLength='6'
required></input>
</div>
<div className="form-group">
<label htmlFor="exampleInputPassword1">Password</label>
<input
type="password"
className="form-control"
id="exampleInputPassword1"
placeholder="Confirm New Password"
name="re_new_password"
value={re_new_password}
onChange={e => onChange(e)}
minLength='6'
required></input>
</div>
<button type="submit" className="btn btn-primary">Reset Password</button>
</form>
</div>
);
};
export default connect(null, { reset_password_confirm }) (ResetPasswordConfirm);
Sorry for the lo-fi question. I will try to do better.
I tried to use useParams to fetch my uid
const onSubmit = e => {
...
let{uid} = useParams()
}
There are no longer route props in react-router-dom routed components, i.e. there is not any injected match prop. You'll use the useParams hook to access the route path params in RRDv6. You can't use React hooks in nested callbacks, they must be called in the function body of a React component or in custom React hooks. Use the useParams hook in the component body and destructure the uid and token path params. Since you are using hooks you may as well also import and use the useNavigate hook and issue the navigation action at the end of the form's onSubmit handler instead of enqueueing a state update.
import React, { useState } from "react";
import { useParams, useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { reset_password_confirm } from '../actions/auth';
const ResetPasswordConfirm = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
const { uid, token } = useParams();
const [formData, setFormData] = useState({
new_password: '',
re_new_password: ''
});
const onChange = e => setFormData(formData => ({
...formData,
[e.target.name]: e.target.value
}));
const onSubmit = e => {
e.preventDefault();
const { new_password, re_new_password } = formData;
dispatch(reset_password_confirm(uid, token, new_password, re_new_password));
navigate("/");
};
return (
...
);
};
export default ResetPasswordConfirm;
Trying to POST request to send data to database but it always shows 400 bad request.
The AuthReducer file is as follow. Data is not getting posted when done in Frontend but its properly working when tested in postman api.
export const Register = (username, email , password) => async(disptach) => {
try{
disptach({type:REGISTER_USER_REQUEST})
const config = {
Headers:{
'Content-Type':'application/json'
}
}
const { data } = await axios.post('/EShop/register', {username ,email , password} , config)
disptach({
type:REGISTER_USER_SUCCESS,
payload:data.user
})
}catch(error){
disptach({
type:REGISTER_USER_FAIL,
payload : error.response.data.message
})
}
}
The register form is as follow..
import React, { useState, useEffect } from "react";
import { Link, useNavigate } from "react-router-dom"
import { useSelector, useDispatch } from "react-redux"
import Loader from "./loader";
import { Register } from "../actions/UserAction";
import "../css-files/Account.css"
export default function register() {
const [email, setemail] = useState('');
const [password, setpassword] = useState('');
const [username, setusername] = useState('');
const disptach = useDispatch();
const navigate = useNavigate();
const { isAuthenticated, error, loading } = useSelector(state => state.user)
useEffect(() => {
if (isAuthenticated) {
navigate('/account/login')
}
}, [disptach, isAuthenticated])
const SubmitRegisterHandler = (e) => {
e.preventDefault()
disptach(Register(username, email, password))
}
return (
<div id="Account_container">
{loading ?
<Loader />
:
<div id="wrapper">
<div id="Wrap_First">
<img src="https://res.cloudinary.com/dqxozrie1/image/upload/v1659935744/eshop/online-registration-sign-up_gfb2gs.webp" />
</div>
<div id="Wrap_Second">
<div id="login">
<h2>Create New Account</h2>
<form onSubmit={SubmitRegisterHandler}>
<input
required
type="text"
placeholder="Username"
value={username}
onChange={(e) => { setusername(e.target.value) }}
/>
<input
required
type="email"
placeholder="Email"
value={email}
onChange={(e) => { setemail(e.target.value) }}
/>
<input
required
type="password"
placeholder="Password"
value={password}
onChange={(e) => { setpassword(e.target.value) }}
/>
<button>Register</button>
</form>
<p id="existing_acc"><Link to="/account/login">Already have an account !</Link></p>
</div>
</div>
</div>
}
</div>
);
}
It gives 400 bad request always. Please help me how to resolve this issue.
import "./App.css";
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { addUser} from "./features/Users";
function App() {
const dispatch = useDispatch();
const userList = useSelector((state) => state.users.value);
const [name, setName] = useState("");
const [username, setUsername] = useState("");
return (
<div className="App">
{" "}
<div className="addUser">
<input
type="text"
placeholder="Name..."
onChange={(event) => {
setName(event.target.value);
}}
/>
<input
type="text"
placeholder="Username..."
onChange={(event) => {
setUsername(event.target.value);
}}
/>
<button
onClick={() => {
dispatch(
addUser({
id: userList[userList.length - 1].id + 1,
name,
username,
})
);
}}
>
{" "}
Add User
</button>
</div>
);}
I am new to react and redux. After clicking the "Add User" button, new User data from inputs in the code will be added to the backend list. I want the values in input sections to be cleared after clicking the "Add User" button, but I don't know how to do.
you need to clear your state after click on submit button. for ex: set function like =>
const clearData = {
setName("")
setUsername("")
}
and pass the func to your onClick event.
onClick={clearData}
The following code will work perfectly fine.
Just assign value={name} and value={username} to both input types respectively and when you click Add User just clear the data in both the states.
import "./App.css";
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { addUser} from "./features/Users";
function App() {
const dispatch = useDispatch();
const userList = useSelector((state) => state.users.value);
const [name, setName] = useState("");
const [username, setUsername] = useState("");
return (
<div className="App">
{" "}
<div className="addUser">
<input
type="text"
placeholder="Name..."
value={name}
onChange={(event) => {
setName(event.target.value);
}}
/>
<input
type="text"
placeholder="Username..."
value={username}
onChange={(event) => {
setUsername(event.target.value);
}}
/>
<button
onClick={() => {
setName("");
setUsername("");
dispatch(
addUser({
id: userList[userList.length - 1].id + 1,
name,
username,
})
);
}}
>
{" "}
Add User
</button>
</div>
);}
You can maintain a simple variable with list of form fields and can update the form state with the variable when you needed to clear form data. The below approach comes handy when you need to add additional fields as well.
import "./App.css";
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { addUser} from "./features/Users";
const formFields = { name: '', username: '' };
function App() {
const dispatch = useDispatch();
const userList = useSelector((state) => state.users.value);
const [params, setParams] = useState(formFields)
const handleChange = (e) => {
const { name, value } = e.target;
setParams({ ...params }, ...{[name]: value});
}
const clearForm = () => setParams(formFields);
return (
<div className="App">
<div className="addUser">
<input
type="text"
placeholder="Name..."
value={params.name}
onChange={(e) => handleChange(e)}
/>
<input
type="text"
placeholder="Username..."
value={params.username}
onChange={(e) => handleChange(e)}
/>
<button
onClick={() => {
dispatch(
addUser({
id: userList[userList.length - 1].id + 1,
...params
})
);
clearForm();
}}
>
{" "}
Add User
</button>
</div>
</div>
)
}
import React,{useState,useEffect} from 'react';
import { Button, Form } from 'semantic-ui-react';
import axios from 'axios';
import {useNavigate} from 'react-router';
import usePrevious from './prev';
import {Link} from 'react-router-dom';
const Update = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckBox] = useState(false);
const [id, setID] = useState(null);
let navigate = useNavigate();
Here I am storing the input field's previous value using another component
to get the previous value
const previous = usePrevious(firstName);
useEffect(() => {
setID(localStorage.getItem('ID'));
setFirstName(localStorage.getItem('First Name'));
setLastName(localStorage.getItem('Last Name'));
setCheckBox(localStorage.getItem('Checkbox Value'))
}, []);
This is where the updated data is being sent to mock api and in if condition i am
comparing previous value with new one(if it changes).
const updateApiData = () => {
axios.put(`https://61cb2af8194ffe0017788c01.mockapi.io/fakeData/${id}`,{
firstName,
lastName,
checkbox
}).then(()=>{
navigate('/read');
})
if(firstName==previous){
console.log("change");
}
}
return(
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input id="i1" placeholder='First Name' value={firstName}
onChange={(e)=>setFirstName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder='Last Name' value={lastName}
onChange={(e)=>setLastName(e.target.value)} />
</Form.Field>
here on button click i am calling the function of sending data to api.
i need to check here if on click update the field's value is same as the previous one.
<Button type='submit' onClick={updateApiData}>Update</Button>
<Link to="/read">
<Button>Cancel</Button>
</Link>
</Form>
<br></br>
<Button onClick={()=>navigate(-1)}>Go Back</Button>
</div>
)
}
export default Update;
So I am passing in some data that i have saved in a state. I am then trying to pass that information as props on to another component. However, when I console.log it shows as undefined.
Here is the page i am passing information from:
import React, { useState } from 'react'
import { Link } from 'react-router-dom'
import axios from 'axios'
import IpContext from '../../IpContext'
import { useContext } from 'react';
import ReactDOM from 'react-dom';
import PostIssues from '../Trainee/PostIssues/PostIssues';
const LoginPage = props => {
const [userDetails, setuserDetails] = useState([]);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [memberType, setMemberType] = useState("");
const getLogin = (e) => {
e.preventDefault();
if (memberType === "trainee") {
axios.get("http://" + ip + "/trainee/findByUsername/" + username)
.then(response => {
setuserDetails(response.data);
console.log(userDetails)
console.log(response.data.id);
}).catch(error => {
console.log(error)
});
} else {
console.log("ignore")
}
}
const validate = (e) => {
if (userDetails.username === username && userDetails.password === password) {
props.history.push("/postIssue");
// userDetails[0].map((issue) => (
<PostIssues
// number={number}
userDetails={userDetails}
/>
}
else {
e.preventDefault();
ReactDOM.render(<p style={{ color: "red" }}>Username/Password wrong</p>, document.getElementById('failed-message'));
}
}
return (
<>
<div className="loginDiv">
<h1 className="loginHeading">Login</h1>
<div>
<form className="ml-3" id="loginForm" onSubmit={validate}>
<input name="username" className="loginInput" type="text" id="username" placeholder="Enter your username" onChange={e => setUsername(e.target.value)} required></input> <br></br>
<input name="password" className="loginInput" type="password" id="password" placeholder="Enter your password" onChange={e => setPassword(e.target.value)} required></input> <br></br>
<select defaultValue="" name="traineeTrainer" onInput={e => setMemberType(e.target.value)} onChange={getLogin} >
<option value="" disabled hidden >Position</option>
<option value="trainer">Trainer</option>
<option value="trainee">Trainee</option>
</select>
<button className="btn btn-primary" id="loginButton" type="submit">Login</button>
<div>
<Link to="/createAccount">
<button style={{ backgroundColor: "darkred" }} className="btn btn-primary" id="signUpButton" type="button">Create an account</button>
</Link>
</div>
</form>
</div>
</div>
{/* Login failed will appear here */}
<div id="failed-message"></div>
</>
)
}
export default LoginPage
And this is where i want to receive information:
import React, {useState, useEffect} from 'react'
import axios from 'axios'
import Issue from '../../Trainer/Issue';
import IpContext from '../../../IpContext'
import { useContext } from 'react';
const PostIssues = props => {
console.log(props.userDetails.username);
return(
)
}
export default PostIssues;
When I run this on the browser I get and error which says
"TypeError: Cannot read property 'username' of undefined".
Why is it undefined if i am passing it as props?
Thanks in advance!
You're not actually returning anything, even though you have a return() in there. Try return(null) and read this answer to see why.
Additionally, I would recommend you try to debug this by using the developer tools in your browser. The React tools are quite handy and they allow you to inspect props and state.
Try rendering props.userDetails.username in a <div> inside your return statement to see the page render the component.