I am creating an application where I am getting a parameter from a function and if the parameter equals true I would render a new route instead.
I know how to use react-router-dom as to render new routes you would use something like this
<Link to="/login">Login</Link>
But I don't know how to call it in a function.
function functionName(success){
if (success){
//What do I write here?
// Something like go to path="/login"
}
}
Thank you
(edit)
import { useContext, useState, useEffect } from "react";
import { AuthContext } from "../../Context Api/authenticationAPI";
import { FaUserPlus } from "react-icons/fa";
import { Link, useHistory } from "react-router-dom";
import Alerts from "./Alerts";
const Register = () => {
const history = useHistory();
const { addUser } = useContext(AuthContext);
const data = useContext(AuthContext).data;
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
useEffect(() => {
console.log(data);
if (data.success) {
history.push("/login");
}
}, [data]);
return (
<div className="row mt-5">
<div className="col-md-6 m-auto">
<div className="card card-body">
<h1 className="text-center mb-3">
<i>
<FaUserPlus />
</i>{" "}
Register
</h1>
<Alerts />
<form>
<div className="mb-2">
<label>Name</label>
<input
type="name"
id="name"
name="name"
className="form-control"
placeholder="Enter Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className="mb-2">
<label>Email</label>
<input
type="email"
id="email"
name="email"
className="form-control"
placeholder="Enter Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="mb-2">
<label>Password</label>
<input
type="password"
id="password"
name="password"
className="form-control"
placeholder="Create Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<button
onClick={(e) => {
e.preventDefault();
addUser({ name, email, password });
}}
className="btn btn-primary col-12"
>
Register
</button>
<p className="lead mt-4">
Have An Account? <Link to="/login">Login</Link>
</p>
</form>
</div>
</div>
</div>
);
};
export default Register;
import React from "react";
import { Link } from "react-router-dom";
import { FaSignInAlt } from "react-icons/fa";
const Login = () => {
return (
<div className="row mt-5">
<div className="col-md-6 m-auto">
<div className="card card-body">
<h1 className="text-center mb-3">
<i>
<FaSignInAlt />
</i>{" "}
Login
</h1>
<div className="mb-2">
<label>Email</label>
<input
type="email"
id="email"
name="email"
className="form-control"
placeholder="Enter Email"
/>
</div>
<div className="mb-2">
<label>Password</label>
<input
type="password"
id="password"
name="password"
className="form-control"
placeholder="Enter Password"
/>
</div>
<button className="btn btn-primary col-12">Login</button>
<p className="lead mt-4">
No Account? <Link to="/register">Register</Link>
</p>
</div>
</div>
</div>
);
};
export default Login;
You can make use of the history object and programmatically navigate using history.push()
import { useHistory } from 'react-router-dom'
const history = useHistory();
function functionName(success){
if (success) {
history.push('/login')
}
}
Reference
useHistory Hook
Related
I am learning React now . I have made a page called as App.js which is a Login Page.I have navigated it to another page App2.js . The navigation process is being done , but I am not able to see the contents in that page .
Here is my Code:-
App.js
import React from "react";
import "./App.css";
//import './App2'
import { Navigate } from "react-router-dom";
function App() {
const [goToContact, setGoToContact] = React.useState(false);
if (goToContact) {
return <Navigate to="/App2" />;
}
return (
<div className="LoginPage">
<div className="topnav">
<h1 className="Heading">E-Commerce App</h1>
</div>
<div className="card">
<div className="container">
<h1 className="SignUp">Sign Up</h1>
<form>
<label for="email" className="email">
<b>Email</b>
</label>
<br />
<input type="email" name="email" placeholder="Enter your email" />
<br />
<label for="psw" className="Password">
<b>Password</b>
</label>
<br />
<input
type="password"
name="Password"
placeholder="Enter your password"
/>
<br />
<label for="psw-repeat">
<b>Repeat Password</b>
</label>
<br />
<input
type="password"
name="Repeat Password"
placeholder="Repeat Password"
/>
<br />
<input type="checkbox" name="Remember Me" className="remember" />
<label for="vehicle1"> Remember Me</label>
<br />
<div class="clearfix">
<button
type="button"
class="cancelbtn"
onClick={() => {
setGoToContact(true);
}}
>
Login
</button>
<button type="submit" class="signupbtn">
Sign Up
</button>
</div>
</form>
</div>
</div>
</div>
);
}
export default App;
App2.js
import React from "react";
function App2() {
return (
<div>
<h1>Hello</h1>
</div>
);
}
export default App2;
``
This is the file structure of my React Application. It is under a src file.
Output of App.js
Output of App2.js
#KarthikKK Phil's comment is what you're looking for. Look into the concept of routing and you will see that you will have one component which will decide which route (component) to render.
First you will need to setup the router:
In your index.js:
import * as React from "react";
import * as ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
{/* The rest of your app goes here */}
</BrowserRouter>,
root
);
Then your App.js:
function App() {
return (
<Routes>
<Route path="/" element={<App1 />} />
<Route path="/app2" element={<App2 />} />
</Routes>
);
}
const App1 = () => {
return (
<div className="LoginPage">
<div className="topnav">
<h1 className="Heading">E-Commerce App</h1>
</div>
<div className="card">
<div className="container">
<h1 className="SignUp">Sign Up</h1>
<form>
<label htmlFor="email" className="email">
<b>Email</b>
</label>
<br/>
<input type="email" name="email" placeholder="Enter your email"/>
<br/>
<label htmlFor="psw" className="Password">
<b>Password</b>
</label>
<br/>
<input
type="password"
name="Password"
placeholder="Enter your password"
/>
<br/>
<label htmlFor="psw-repeat">
<b>Repeat Password</b>
</label>
<br/>
<input
type="password"
name="Repeat Password"
placeholder="Repeat Password"
/>
<br/>
<input type="checkbox" name="Remember Me" className="remember"/>
<label htmlFor="vehicle1"> Remember Me</label>
<br/>
<div className="clearfix">
<button
type="button"
className="cancelbtn"
onClick={() => {
navigate('/app2');
}}
>
Login
</button>
<button type="submit" className="signupbtn">
Sign Up
</button>
</div>
</form>
</div>
</div>
</div>
)
}
const App2 = () => {
return (
<div>
<h1>Hello</h1>
</div>
);
}
export default App;
Full documentation (worth spending a couple hours really understanding this):
https://reactrouter.com/en/main/start/overview
This is index.js, replace this with yours, if you haven't made any change in index.js.
import React from "react";
import { createRoot } from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import "./index.css";
import App from "./App";
import App2 from "./App2";
import reportWebVitals from "./reportWebVitals";
const router = createBrowserRouter([
{
path: "/",
element: <App />,
},
{
path: "/App2",
element: <App2 />,
},
]);
createRoot(document.getElementById("root")).render(
<RouterProvider router={router} />
);
reportWebVitals();
You have to define the route before you use it. You can define it with what component you need render on that route.
Documentation: https://reactrouter.com/en/main/start/overview
import axios from "axios";
import React from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import { useForm } from "react-hook-form";
import { toast, ToastContainer } from "react-toastify";
import auth from "../../firebase.init";
const AddInventoryItems = () => {
const { register, handleSubmit } = useForm();
const [user] = useAuthState(auth);
const onSubmit = (data) => {
axios.post("http://localhost:5000/item", data).then((res) => {
const { data } = res;
if (data) {
toast("You have added a new item, Yeah!!!");
}
});
};
return (
<div className="row w-25 mx-auto">
<form
className="d-flex flex-column my-5 col-sm-12 col-md-6"
onSubmit={handleSubmit(onSubmit)}
>
<input
placeholder="Enter Name"
className="mb-2"
value={user.displayName}
type="text"
{...register("user name")}
required
/>
<input
placeholder="Enter Email"
className="mb-2"
type="email"
value={user.email}
{...register("email")}
/>
<input
placeholder="Image Url"
className="mb-2"
type="text"
{...register("image")}
/>
<input
placeholder="Item name"
className="mb-2"
{...register("name", { required: true, maxLength: 20 })}
/>
<input
placeholder="Item description"
className="mb-2"
{...register("description")}
/>
<input
placeholder="Item price"
className="mb-2"
type="number"
{...register("price", { min: 18, max: 99 })}
/>
<input
placeholder="Item quantity"
className="mb-2"
type="number"
{...register("quantity", { min: 18, max: 99 })}
/>
<input
placeholder="Supplier name"
className="mb-2"
{...register("supplier name")}
/>
<input
className="btn btn-outline-primary"
type="submit"
value="Add new item"
/>
</form>
<ToastContainer />
</div>
);
};
export default AddInventoryItems;
To make responsive form elements, you have to wrap all the inputs in form-group class and in their inputs you have to add class form-control
example:
<div class="form-group">
<label for=""></label>
<input type="email" class="form-control" />
</div>
take a look on Bootstrap documentation:
https://getbootstrap.com/docs/5.1/forms/overview/
Use form-control class in your form input field. So your form field will be responsive.
<form className="d-flex flex-column my-5 col-sm-12 col-md-6 form-control" onSubmit={handleSubmit(onSubmit)}>
You can also see bootstrap official documentation for more detail
I'm trying to create a simple React site where a user can sign up on the home page or sign in if the user already has an account.
I want the home page to be the SignUp component if the user has not signed up or signed in, but I want a different home page if a user is logged in.
I'm using Axios to post/get the user information. It posts information correctly but nothing happens after the user adds a new user!
Here is my code:
Layout Component:
import React, {Component} from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import AboutUs from '../AboutUs';
import Header from '../Header';
import SignUp from '../SignUp';
import Home from '../Home';
export default class Layout extends Component {
constructor(props) {
super(props);
this.state = {
loggedInUser: ''
};
}
setLoggedInUser = (user) => {
this.setState({
loggedInUser: user
});
this.props.history.push('/');
};
render() {
// THESE JUST DETERMINE WHAT THE HOME URLs SHOULD BE, IF LOGGED IN.
// MUST STILL USE LOGIC TO RE-DIRECT.
let routes = (
<React.Fragment>
<Route path='/sign-up' component={SignUp} exact />
<Route path='/' component={SignUp} exact />
</React.Fragment>
)
if (this.loggedInUser) {
routes = (
<React.Fragment>
<Route path='/home' component={Home} exact />
<Route path='/' component={Home} exact />
</React.Fragment>
)
}
return (
<div>
<Header submit={this.signInSubmitHandler} loggedInUser={this.state.loggedInUser} />
<Route path='/about' component={AboutUs} exact />
{routes}
</div>
);
}
}
Header Component:
import React, {Component} from 'react';
import {NavLink} from 'react-router-dom';
import axios from 'axios';
export default class Header extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
};
this.handleChange = this.handleChange.bind(this);
this.signInSubmitHandler = this.signInSubmitHandler.bind(this);
}
handleChange = (event) => {
this.setState({
[event.target.name]: event.target.value
});
};
signInSubmitHandler = (event) => {
event.preventDefault();
const user = {
email: this.state.email,
password: this.state.password
};
axios.post("http://localhost:8080/login", user)
.then(
response => { this.props.setLoggedInUser(response.data); }
)
.catch(
response => { console.log("In the future, add logic to navigate to an error page.") }
);
if (user !== null){
alert("User signed in successfully!");
}
//super.setLoggedInUser(user);
}
render() {
let links;
let searchBar;
return (
<div>
<nav className="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<NavLink className="navbar-brand" to="/">Student Portal</NavLink>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarCollapse">
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<NavLink className="nav-link" to="/about">About</NavLink>
</li>
<li className="nav-item">
<NavLink className="nav-link" to="/sign-out">Sign Out</NavLink>
</li>
</ul>
{/*<form className="form-inline mt-2 mt-md-0">
<input className="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search" />
<button className="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>*/}
<form onSubmit={this.signInSubmitHandler} className="search-bar form-inline mt-2 mt-md-0">
<input name="email" value={this.state.value} onChange={this.handleChange} className="form-control mr-sm-2" type="text" placeholder="E-mail" aria-label="email" />
<input name="password" value={this.state.value} onChange={this.handleChange} className="form-control mr-sm-2" type="text" placeholder="Password" aria-label="password" />
<button type="submit" className="btn btn-outline-success my-2 my-sm-0">Sign In</button>
</form>
</div>
</nav>
</div>
);
}
}
Sign In Component:
import React, {Component} from 'react';
import '../css/SignUp.css';
import axios from 'axios';
export default class SignUp extends Component {
constructor(props) {
super(props);
this.state = {
firstName: '',
lastName: '',
age: '',
telephone: '',
email: '',
password: '',
addedUser: false
};
this.handleChange = this.handleChange.bind(this);
this.signUpSubmitHandler = this.signUpSubmitHandler.bind(this);
}
handleChange = (event) => {
const name = event.target.value;
const value = event.target.value;
this.setState({
[event.target.name]: event.target.value
});
}
signUpSubmitHandler = (event) => {
event.preventDefault();
const student = {
firstName: this.state.firstName,
lastName: this.state.lastName,
age: this.state.age,
telephone: this.state.telephone,
email: this.state.email,
password: this.state.password
};
axios.post("http://localhost:8080/submitStudentDetails", student)
.then(
response => {
alert("Added " + this.state.firstName)
}
)
.catch(
error => {
alert("Error")
}
);
}
render() {
return (
<div>
<div className="container">
<div className="col-md-6 mx-auto text-center">
<div className="header-title">
<h1 className="wv-heading--title">
Sign up — it’s free!
</h1>
<h2 className="wv-heading--subtitle">
Lorem ipsum dolor sit amet! Neque porro quisquam est qui do dolor amet, adipisci velit...
</h2>
</div>
</div>
<div className="row">
<div className="col-md-4 mx-auto">
<div className="myform form ">
<form onSubmit={this.signUpSubmitHandler} name="signUp">
<div className="form-group">
<input type="text" name="firstName" value={this.state.value} onChange={this.handleChange} className="form-control" id="firstName" placeholder="First Name" />
</div>
<div className="form-group">
<input type="text" name="lastName" value={this.state.value} onChange={this.handleChange} className="form-control" id="lastName" placeholder="Last Name" />
</div>
<div className="form-group">
<input type="text" name="age" value={this.state.value} onChange={this.handleChange} className="form-control" id="age" placeholder="Age" />
</div>
<div className="form-group">
<input type="text" name="telephone" value={this.state.value} onChange={this.handleChange} className="form-control" id="telephone" placeholder="Telephone" />
</div>
<div className="form-group">
<input type="text" name="email" value={this.state.value} onChange={this.handleChange} className="form-control" id="email" placeholder="E-mail" />
</div>
<div className="form-group">
<input type="text" name="password" value={this.state.value} onChange={this.handleChange} className="form-control" id="password" placeholder="Password" />
</div>
<div className="text-center ">
<button type="submit" className=" btn btn-block send-button tx-tfm">Create Your Free Account</button>
</div>
<div className="col-md-12 ">
<div className="login-or">
<hr className="hr-or" />
</div>
</div>
<p className="small mt-3">By signing up, you are indicating that you have read and agree to the Terms of Use and Privacy Policy.
</p>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
Home Component:
import React, {Component} from 'react';
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
students: ''
}
}
render() {
return (
<div>
<h1>HOME: logged in!</h1>
<p>Welcome!</p>
</div>
);
}
}
you must change
if (this.loggedInUser)
// to
if (this.state.loggedInUser)
I have made a bank account submit form. I want to save the data which is entered in the form into redux store. How can I take input value from form and store it in redux store variable ?
My client.js file has redux store and form.js is the component from which I need to get the input values.
client.js:
import { combineReducers, createStore } from 'redux';
const addUserReducer = (state={}, action) => {
switch(action.type){
case: "CHANGE_FIRSTNAME"{
state = {...state, firstname:action.payload }
break;
}
case: "CHANGE_LASTNAME"{
state = {...state, lastname:action.payload }
break;
}
case: "CHANGE_EMAILID"{
state = {...state, emailid:action.payload }
break;
}
case: "CHANGE_IBAN"{
state = {...state, iban:action.payload }
break;
}
case: "CHANGE_BANKNAME"{
state = {...state, bankname:action.payload }
break;
}
}
return state;
}
const reducers = combineReducers({
addUser:addUserReducer
})
const store = createStore(reducers);
store.subscribe(() => {
console.log('Store changed', store.getState());
})
store.dispatch({type: "CHANGE_FIRSTNAME", payload:"Will"});
store.dispatch({type: "CHANGE_LASTNAME", payload:"Groot"});
store.dispatch({type: "CHANGE_EMAILID", payload:"xyz#gmail.com"});
store.dispatch({type: "CHANGE_IBAN", payload:3234243242});
store.dispatch({type: "CHANGE_BANKNAME", payload:"XYZ"});
form.js:
import React, { Component } from "react";
import "./form.css";
class Form extends Component {
render() {
return (
<div>
<div id="center">
<form>
<div className="form-group">
<label for="firstname">First Name:</label>
<input type="firstname" className="form-control" id="firstname" />
</div>
<div className="form-group">
<label for="lastname">Last Name:</label>
<input type="lastname" className="form-control" id="lastname" />
</div>
<div className="form-group">
<label for="email">Email address:</label>
<input type="email" className="form-control" id="email" />
</div>
<div className="form-group">
<label for="bankacc">IBAN:</label>
<div id="deletebank" className="items">
<input type="bankacc" className="form-control" id="bankacc" />
<button type="button" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-trash" />
</button>
</div>
</div>
<div className="form-group">
<label for="bankname">Bank Name:</label>
<input type="bankname" className="form-control" id="bankname" />
</div>
<div className="form-group">
<button type="button" className="btn addbank">
+ Add bank account
</button>
</div>
<div className="form-group">
<button type="button" class="btn btn-success">
Submit
</button>
</div>
</form>
</div>
</div>
);
}
}
export default Form;
Screenshot of my form:
I would recommend react-redux to connect your components with redux store, however it is still doable without it:
Create action creators that will update specific variable in the store:
import { bindActionCreators } from "redux";
const updateFirstName = name => ({ type: "CHANGE_FIRSTNAME", payload: name });
const updateLastName = lastName => ({
type: "CHANGE_LASTNAME",
payload: lastName
});
const updateEmail = email => ({ type: "CHANGE_EMAILID", payload: email });
const updateIban = iban => ({ type: "CHANGE_IBAN", payload: iban });
const updateBankName = bankName => ({
type: "CHANGE_BANKNAME",
payload: bankName
});
Now bind your action creators with dispatch, so calling actionCreators.updateFirsName('something') will actually dispatch an action to the store.
export const actionCreators = bindActionCreators(
{
updateFirstName,
updateLastName,
updateEmail,
updateIban,
updateBankName
},
store.dispatch
);
Now you only need to call each store-updating function whenever theres an change on the input:
import React, { Component } from "react";
import "./form.css";
import { actionCreators } from "/path/to/store";
class Form extends Component {
render() {
return (
<div>
<div id="center">
<form>
<div className="form-group">
<label for="firstname">First Name:</label>
<input
type="firstname"
className="form-control"
id="firstname"
onChange={e => actionCreators.updateFirstName(e.target.value)}
/>
</div>
<div className="form-group">
<label for="lastname">Last Name:</label>
<input
type="lastname"
className="form-control"
id="lastname"
onChange={e => actionCreators.updateLastName(e.target.value)}
/>
</div>
<div className="form-group">
<label for="email">Email address:</label>
<input
type="email"
className="form-control"
id="email"
onChange={e => actionCreators.updateEmail(e.target.value)}
/>
</div>
<div className="form-group">
<label for="bankacc">IBAN:</label>
<div id="deletebank" className="items">
<input
type="bankacc"
className="form-control"
id="bankacc"
onChange={e => actionCreators.updateIban(e.target.value)}
/>
<button type="button" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-trash" />
</button>
</div>
</div>
<div className="form-group">
<label for="bankname">Bank Name:</label>
<input
type="bankname"
className="form-control"
id="bankname"
onChange={e => actionCreators.updateBankName(e.target.value)}
/>
</div>
<div className="form-group">
<button type="button" className="btn addbank">
+ Add bank account
</button>
</div>
<div className="form-group">
<button type="button" class="btn btn-success">
Submit
</button>
</div>
</form>
</div>
</div>
);
}
}
export default Form;
I am facing circular dependency issue in my modal where there is signup form and a login button in the signup form for already registered user. Also login form has then signup button for not already registered user. I have heard es6 solves circular dependency issue but i am still getting it. How can i solve this issue?
WARNING in Circular dependency detected:
app/containers/LoginContainer/index.js ->
app/containers/Register/index.js ->
app/containers/LoginContainer/index.js
WARNING in Circular dependency detected:
app/containers/Register/index.js ->
app/containers/LoginContainer/index.js ->
app/containers/Register/index.js
import Login from "containers/LoginContainer";
const mapDispatchToProps = dispatch => ({
showDialog: dialog => dispatch(showDialog(dialog)),
hideDialog: () => dispatch(showDialog("null"))
});
class Register extends React.Component {
render() {
const { show_password, user } = this.state;
return (
<Modal show onHide={() => this.props.hideDialog()}>
<form onSubmit={this.handleSubmit}>
<div className="form-group form-block">
<input
type="text"
name="first_name"
className="form-control-form "
placeholder="First Name"
onChange={this.handleChange}
/>
</div>
<div className="form-group form-block">
<input
type="text"
name="last_name"
className="form-control-form "
placeholder="Last Name"
onChange={this.handleChange}
/>
</div>
<div className="form-group form-block">
<input
type="email"
name="email"
className="form-control-form "
placeholder="Email"
onChange={this.handleChange}
/>
</div>
<div className="form-group form-block">
<input
type={show_password ? "text" : "password"}
name="password"
className="form-control-form"
placeholder="Password"
onChange={this.handleChange}
/>
</div>
</form>
<Modal.Footer>
<a
className="btn-gst"
onClick={() => this.props.showDialog(<Login />)}
>
Login
</a>
</Modal.Footer>
</Modal>
);
}
}
import Register from 'containers/Register';
<Modal show onHide={() => this.props.hideDialog()}>
<form onSubmit={this.handleSubmit}>
<div className="form-group form-block">
<input
type="text"
name="username"
/>
</div>
<div className="form-group form-block">
<input
type="password"
name="password"
required
/>
</div>
<div className="row">
<div className="col-md-6">
<div className="checkbox meta">
<label>
<input type="checkbox" /> Remember me
</label>
</div>
</div>
</form>
<Modal.Footer>
<a
className="btn-gst"
onClick={() => this.props.showDialog(<Register />)}
>
Sign Up
</a>
</Modal.Footer>
</Modal>