Getting my page to Route properly with ReactJS - reactjs

Have a pretty basic app through ReactJS but having trouble with routing to a new page and can't figure out why. When I click on the box that should route me to the Quiz page, the contents on that page populate (just saying "hello") but everything else on the page stays the same. I thought it had to do with the exact path but even still, everything remains the same and doesnt just show what's within my Quiz Component. Any thoughts? Appreciate all the help!
APP.JS
import React, { Component } from 'react';
import { Route, Link, Switch } from 'react-router-dom';
import Home from "./Components/Home/Home"
import Header from "./Components/Header/Header"
import Modal from "./Components/Modal/Modal"
import Quiz from "./Components/Quiz/Quiz"
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
questions: this.props.questions,
show: false,
};
}
// Function that opens/closes Modal
showModal = () => {
this.setState({ show: !this.state.show })
}
render() {
return (
<div>
<header>
<Header />
{/* Input button for Modal */}
<input
className='open-modal-btn'
type='button'
onClick={this.showModal}
value=' Show Modal'
/>
<Modal show={this.state.show} onClose={this.showModal}>
This message is from Modal
</Modal>
</header>
<Home />
<div>
<Switch>
<Route
exact
path='/quiz'
render={() => {
return (
<Quiz />
);
}}
/>
</Switch>
</div>
</div>
);
}
}
export default App;
Home.JS
import React, { Component } from 'react';
import './Home.css';
import { Link } from 'react-router-dom';
class Home extends Component {
constructor(props) {
super(props);
this.state = { username: '' };
}
// Updates the name of the User input Box
handleChange = (event) => {
this.setState({ username: event.target.value });
};
render() {
return (
<main>
<div>
<form>
<label htmlFor='Username'> Username: </label>
<input
type='text'
name='username'
value={this.state.username}
onChange={this.handleChange}
/>
</form>
<div className='Allboxes'>
<div className='boxOne'>
<b> Name: </b> {this.state.username} <br />
<b> From: </b> Boston, MA <br />
<b> Interests: </b>Long walks on the beach, Golden Girls <br />
</div>
<div className='boxTwo'>
<b> Name: </b> {this.state.username} <br />
<b> From: </b> Dallas, TX <br />
<b> Interests: </b>Opera, Dank Memes <br />
</div>
<div className='boxThree'>
<b> Name: </b> {this.state.username} <br />
<b> From: </b> Long Beach, CA <br />
<b> Interests: </b>Shredding the Gnar, playing with yoyo's <br />
</div>
<Link to='/quiz'>
<div className='boxFour'>
<b> Name: </b> {this.state.username} <br />
<b> From: </b> Chicago, IL <br />
<b> Interests: </b>Pokemon, More Pokemon, Daisies <br />
</div>
</Link>
</div>
</div>
</main>
);
}
}
export default Home;
QUIZ.JS
import React, { Component } from 'react';
class Quiz extends Component {
render() {
return (
<div>
Hello
</div>
);
}
}
export default Quiz;
HEADER.JS
import React, { Component} from 'react';
import './Header.css';
import { Link } from 'react-router-dom';
class Header extends Component {
render() {
return (
<div>
<h1> Who Wants to be a Tandem Millionaire </h1>
<Link to='/'> Home </Link>
</div>
);
}
}
export default Header;
MODAL.JS
import React, { Component } from 'react';
import './Modal.css';
export default class Modal extends React.Component {
// Function that closes the Modal Button
onClose = (e) => {
this.props.onClose && this.props.onClose(e);
};
render() {
if (!this.props.show) {
return null;
}
return (
<div className='backdropStyle'>
<div className='modalStyle'>
{this.props.children}
<div className='footerStyle'>
<button
className='close-modal-btn'
onClick={(e) => {
this.onClose(e);
}}>
Close
</button>
</div>
</div>
</div>
);
}
}

I think the bug here could be that you did not wrap your App.js with Browser Router
Code below is a simple structuring of react-router
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom'
import React from 'react'
const App = ()=>{
<Router>
<Switch>
<Route path="/another-route" exact={true}>
<AnotherComponent />
</Route>
<Route path="/" exact={true}>
<HomeComponent />
</Route>
</Switch>
</Router>
}
So following such a structure will get your React Routing well and even cleaner having App.js structured in such format,
You can also refer to the documentation if what I wrote does not make any sense
https://reactrouter.com/web/guides/quick-start

Related

How can I get the input of a textfield in ReactJS? I am trying to make a specific calculator and need the inputs from the User

I am using material-UIs text fields and want to get the value from the user's input. Right now I am just trying to log the value to the console, so I can see it is getting the value but, it is logging blank. How can I get the Input from the text field?
The Input cards are a component with the text field along with a few other design things.
import "./StartPage.scss";
import React, { Component } from "react";
import InputCard from '../components/InputCard';
import {BrowserRouter as Router, Switch, Route, Link} from 'react-router-dom';
import ResultsPage from '../pages/ResultsPage';
import InputToFormula from "../components/InputToFormula";
import PropTypes from 'prop-types';
import { evaluate } from "mathjs";
import * as math from "mathjs";
import { tsConstructorType } from "#babel/types";
class StartPage extends Component {
constructor(props) {
super(props);
this.state = {
setBots: "",
setEmployees: "",
setSalary: "",
setTime: ""
};
};
handleBots = event => {
this.setState({ setBots: event.target.value});
};
handleEmployees = event => {
this.setState({ setEmployees: event.target.value});
};
handleSalary = event => {
this.setState({ setSalary: event.target.value});
};
handleTime = event => {
this.setState({ setTime: event.target.value});
};
logValue = () => {
console.log(this.state.setBots);
};
render(){
return (
<div className="container">
<div className="header-container">
<h2> </h2>
<h1>Return on Investment Calculator</h1>
<h2> </h2>
</div>
<form>
<div class="inputs input-group">
<InputCard onEvent={this.handleBots} id="Bots" icon="robot" label="Number of Processes" />
<InputCard onEvent={this.handleEmployees} id="Employees" icon="users" label="Number of FTE's" />
<InputCard onEvent={this.handleSalary} id="Salary" icon="dollar-sign" label="Average Salary" />
<InputCard onEvent={this.handleTime} id="Time" icon="clock" label="Average Time (%)" />
</div>
<Router>
<div>
<h1> </h1>
<Link to='/ResultsPage'><button onClick={this.logValue} type="button"
class="btn btn-outline-success submit-button btn-lg">CALCULATE</button></Link>
</div>
<Switch>
<Route path="/ResultsPage" exact>
<ResultsPage />
</Route>
</Switch>
</Router>
</form>
</div>
);
}
}
export default StartPage;
Use onChange instead of onEvent, here you can read more about it

How to get rid of this ? from the url

I'm making a react application and whenever I search for something(eg cat) on the homepage, the url changes to search/cat and the forward, backward button work normally & help me switch between the homepage and the cat search page ...but when i search for something again (eg rat) after(homepage->cat) so the url changes to search/rat? and now when i press the back button the url changes to search/rat and i'm on the same page then if i press back button again the url becomes search/cat but the page still has the results of the rat search and if i press back again ,the homepage appears..why is this happening?I think it's because of the ? that appears at the end of the url..Please help
after searching cat
after searching for rat
after pressing the back button
after pressing the back button
after pressing the back button
This is the code of the search bar
import React, { Component } from "react";
import "./styles/searchBar.scss";
import "font-awesome/css/font-awesome.min.css";
import { withRouter } from "react-router-dom";
import SearchForm from "./SearchForm";
import { connect } from "react-redux";
import { fetchRandomPhotos } from "../redux/actions/randomPhotoAction";
class SearchBar extends Component {
state = {
searchQuery: "",
};
componentDidMount() {
this.props.fetchRandomPhotos();
}
handleChange = (event) => {
this.setState({ searchQuery: event.target.value });
};
handleSubmit = (event) => {
//event.preventDefault();
this.props.history.push(`/search/${this.state.searchQuery}`);
};
handleProfile = () => {
this.props.history.push(`/public/${this.props.photo.user.username}`);
};
render() {
const { photo } = this.props;
return !photo ? (
<div className="search-bar-container">
<div className="search-bar-area">
<div className="about-foto-fab">
<h1>Foto-Fab</h1>
<p>The internet's source of freely-usable images.</p>
<p>Powered by creator everywhere</p>
</div>
<SearchForm
onSubmit={this.handleSubmit}
onChange={this.handleChange}
/>
</div>
</div>
) : (
<div
className="search-bar-container"
style={{ backgroundImage: `url("${photo.urls.full}")` }}
>
<div className="black-layer"></div>
<div className="search-bar-area">
<div className="about-foto-fab">
<h1>Foto-Fab</h1>
<p>The internet's source of freely-usable images.</p>
<p>Powered by creator everywhere</p>
</div>
<SearchForm
onSubmit={this.handleSubmit}
onChange={this.handleChange}
/>
</div>
<div className="picture-info">
<div className="photographer">
<p onClick={this.handleProfile}>
<strong>Photo</strong> by {""}
<strong>{photo.user.name}</strong>
</p>
</div>
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
photo: state.randomPhotoState.photo,
};
};
export default connect(mapStateToProps, { fetchRandomPhotos })(
withRouter(SearchBar)
);
This is the App.js
import React from "react";
import Navbar from "./components/Navbar";
import { BrowserRouter, Switch, Route, Redirect } from "react-router-dom";
import Home from "./pages/Home";
import LoginPage from "./pages/LoginPage";
import ProfilePage from "./pages/ProfilePage";
import SearchPage from "./pages/SearchPage";
import PublicUserProfilePage from "./pages/publicUserProfilePage";
import MobileNavigation from "./components/MobileNavigation";
import AboutPage from "./pages/AboutPage";
function App() {
return (
<BrowserRouter>
<Navbar />
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/login" component={LoginPage} />
<Route exact path="/profile" component={ProfilePage} />
<Route exact path="/search/:searchQuery" component={SearchPage} />
<Route exact path="/about" component={AboutPage} />
<Route
exact
path="/public/:username"
component={PublicUserProfilePage}
/>
<Redirect to="/" />
</Switch>
<MobileNavigation />
</BrowserRouter>
);
}
export default App;
search form component
import React, { Component } from "react";
export class SearchForm extends Component {
render() {
const { onSubmit, onChange } = this.props;
return (
<form className="search-form" onSubmit={onSubmit}>
<input
type="text"
placeholder="Search free high-resolution photos"
onChange={onChange}
/>
<button type="submit">
<i className="fa fa-search"></i>
</button>
</form>
);
}
}
export default SearchForm;
import React, { Component } from "react";
import "./styles/searchBar.scss";
import "font-awesome/css/font-awesome.min.css";
import { withRouter } from "react-router-dom";
import SearchForm from "./SearchForm";
import { connect } from "react-redux";
import { fetchRandomPhotos } from "../redux/actions/randomPhotoAction";
class SearchBar extends Component {
state = {
searchQuery: "",
};
componentDidMount() {
this.props.fetchRandomPhotos();
}
handleChange = (event) => {
this.setState({ searchQuery: event.target.value });
};
handleSubmit = (event) => {
event.preventDefault();
if (this.state.searchQuery) {
this.props.history.push(`/search/${this.state.searchQuery}`);
}
};
handleProfile = () => {
this.props.history.push(`/public/${this.props.photo.user.username}`);
};
render() {
const { photo } = this.props;
return !photo ? (
<div className="search-bar-container">
<div className="search-bar-area">
<div className="about-foto-fab">
<h1>Foto-Fab</h1>
<p>The internet's source of freely-usable images.</p>
<p>Powered by creator everywhere</p>
</div>
<SearchForm
onSubmit={this.handleSubmit}
onChange={this.handleChange}
/>
</div>
</div>
) : (
<div
className="search-bar-container"
style={{ backgroundImage: `url("${photo.urls.full}")` }}
>
<div className="black-layer"></div>
<div className="search-bar-area">
<div className="about-foto-fab">
<h1>Foto-Fab</h1>
<p>The internet's source of freely-usable images.</p>
<p>Powered by creator everywhere</p>
</div>
<SearchForm
onSubmit={this.handleSubmit}
onChange={this.handleChange}
/>
</div>
<div className="picture-info">
<div className="photographer">
<p onClick={this.handleProfile}>
<strong>Photo</strong> by {""}
<strong>{photo.user.name}</strong>
</p>
</div>
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
photo: state.randomPhotoState.photo,
};
};
export default connect(mapStateToProps, { fetchRandomPhotos })(
withRouter(SearchBar)
);

Not able to get the value after updating the state

I have an application which has 3 pages .home ,shop,about.I want to add authentication to only page ie shop. When the user want to go to the shop page he has to login then only the user will go the shop page. I am maintaining a global state which has intital value isLogin:False. I extracted this value through mapStatetoProps in my App.js where all my Routes are there.For /shop path i am using the value as ternary condition. Initially the value (isLogin) is false it will render the Login page upon clicking shop link. But after proper authentication i am unable to redirect to the shop page
//App.js
import React ,{Component} from 'react';
import './App.css';
import Navigation from './Step1/Navbar'
import Home from './Step1/Home'
import Shop from './Step1/Shop'
import About from './Step1/About'
import Login from './LoginAuthentication/Loginform'
import {BrowserRouter as Router,Route} from 'react-router-dom'
import {connect} from 'react-redux'
const mapStateToProps=(state)=>{
console.log(state)
return{
isLogin:state.isLogin
}
}
class App extends Component {
render(){
return (
<Router>
<div className="App">
<Navigation/>
<Route path="/" exact component={Home}/>
<Route path="/about" component={About}/>
<Route path="/shop"
render={({isLogin}) =>(
isLogin ? <Shop/> : <Login/>
) }
/>
</div>
</Router>
);
}
}
export default connect(mapStateToProps,null)(App);
//Navigation
import React from 'react'
import {NavLink} from 'react-router-dom'
const Navbar=()=> {
return (
<div>
<nav className="navbar navbar-expand-sm bg-dark">
<ul className="navbar-nav">
<li className="nav-item"><NavLink to="/" >Home</NavLink> </li>
<li className="nav-item"><NavLink to="/shop">Shop </NavLink> </li>
<li className="nav-item"><NavLink to ="/About">About </NavLink> </li>
<li className="nav-item"><NavLink to ="/page">Page </NavLink> </li>
</ul>
</nav>
</div>
)
}
export default Navbar
// LoginForm.js
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {withRouter} from 'react-router-dom'
//import {Redirect} from 'react-router-dom'
import {action1} from '../Actions/action1'
const mapDispatchToProps=(dispatch)=>{
return{
LoginCheck:()=>dispatch(action1())
}
}
class Loginform extends Component {
state={
username:'',
password:'',
uname:'dharmendra',
pwd:'230498'
}
nameHandler=(event)=>{
if(event.target.name==='UserName'){
this.setState({username:event.target.value})
}
if(event.target.name==='Password'){
this.setState({password:event.target.value})
}
}
submitHandler=(event,state)=>{
event.preventDefault()
const uname=this.state.uname
const pwd=this.state.pwd
if(this.state.username===uname && this.state.password===pwd){
this.props.LoginCheck()
//return <Redirect to="/shop"/>
//this.props.history.push("/shop")
this.props.history.push("/page");
console.log('hi i am in shop page successful')
}
else{
alert("Enter proper Credentials")
}
}
render() {
return (
<div className="login">
<form onSubmit={this.submitHandler}>
<div className="form-group">
<h1>
<input
type="text"
placeholder="UserName"
value={this.state.username}
onChange={this.nameHandler}
className="form-control"
name="UserName"
/>
</h1>
</div>
<br></br>
<div className="form-group">
<h1>
<input
type="password"
placeholder="Password"
value={this.state.password}
onChange={this.nameHandler}
className="form-control"
name="Password"
/>
</h1>
</div>
<br></br>
<div className="form-group">
<button type="submit" className="btn btn-success" >Login</button>
</div>
</form>
</div>
)
}
}
export default withRouter(connect(null,mapDispatchToProps)(Loginform))
//reducer1.js
import {LOGINCHECK} from '../Constants/actiontypes'
const initialState={
isLogin:false
}
const reducer1=(state=initialState,action)=>{
//console.log(action.type)
//console.log(state)
if(action.type===LOGINCHECK){
return Object.assign({},state,{isLogin:true})
}
return state
}
export default reducer1
//action.js
import {LOGINCHECK} from '../Constants/actiontypes'
export const action1 =()=>{
return{
type:LOGINCHECK
}
}
Unable to redirect to the shop page even after proper authentication also
Change the route like this :
<Route path="/shop"
render={() =>(
this.props.isLogin ? <Shop/> : <Login/>
) }
/>
The props that are passed to the render prop in the Route components are route props, not the App component props (they don't contain isLogin)
https://reacttraining.com/react-router/web/api/Route/route-props

Why is my component not effectively receiving props?

I keep getting a message that the item I'm trying to access via props is undefined. Can you please tell me why it's not working?
Here is where the instance where the props are attempting to be passed... I'm specifically talking about the tellus and yourTrial props.
import React from 'react'
import Info from './components/Info'
import Upsell from '../../../general/components/order/components/Upsell'
import FormTwo from '../../../general/components/forms/FormTwo'
import Footer from '../../../cbd-desktop/components/layout/Footer'
export default class Order extends React.Component {
render() {
return (
<div>
<div>
<div style={styles.header}>
<img style={styles.leaf} src="./resources/desktop-img/leaves_top.png" />
<img style={styles.logo} src="./resources/desktop-img/logo_white.png" />
</div>
<div style={styles.wrapper}>
<div style={styles.leftWrapper}>
<Info />
<Upsell styles={upsellStyles} />
</div>
<FormTwo styles={formStyles} tellus="Tell us where to send" yourTrial="YOUR TRIAL BOTTLE"} />
</div>
</div>
<Footer style={styles.footer}/>
</div>
)
}
}
And here is where I am trying to display these values on the child... towards the top in two h2s
import React from 'react'
import { connect } from 'react-redux'
import { stepTwoSubmit, saveBillingData } from
'../../actions/formStepTwoActions'
import { addReceiptProduct } from '../../actions/receiptActions'
import FormTwoInputs from './components/FormTwoInputsComponent.jsx'
import Throbber from '../throbber/Throbber'
import FormWarning from './components/FormWarningComponent.jsx'
import Button from '../../../cbd-desktop/components/layout/Button'
const mapStateToProps = state => ({
state:state,
config:state.config,
downsellProduct:state.downsell.downsellProduct || {},
receiptProducts:state.receipt.receiptProducts || []
})
const mapDispatchToProps = {
stepTwoSubmit,
saveBillingData,
addReceiptProduct
}
#connect(mapStateToProps, mapDispatchToProps)
export default class FormTwo extends React.Component {
constructor(props) {
super(props)
componentWillReceiveProps(nextProps) {
let formTwoResponse = nextProps.state.stepTwo.formTwoResponse
this.checkOrderStatus(formTwoResponse)
}
componentDidMount() {
this.fillMainOrder()
this.calculateViewers()
this.calculateTimer()
}
render() {
let { state, props, inputs, onInputFocus, saveInputVal, styles } = this,
CustomTag = props.labels ? 'label' : 'span',
{ submitting, formWarning } = state,
{ invalidInputID, text, visible } = formWarning
return (
<div style={styles.formWrapper}>
<p style={styles.yellowBanner}>{this.state.viewers} people viewing this product right now</p>
<div style={styles.formInnerWrapper}>
<div style={styles.headerWrapper}>
<h2 style={styles.header}>{this.props.tellus}</h2>
<h2 style={styles.header}>{this.props.yourTrial}</h2>
</div>
<div style={styles.weAccept}>
<p style={styles.weAcceptText}>We Accept:</p>
<img style ={styles.cardImage} src="resources/desktop-img/cards.png" />
</div>
<form onSubmit={this.submit}>
<FormTwoInputs onInputFocus={onInputFocus} saveInputVal={saveInputVal} CustomTag={CustomTag} styles={styles} />
<FormWarning visible={visible} invalidInputID={invalidInputID} text={text} />
<Button style={styles.button} buttonText="RUSH MY TRIAL" />
</form>
</div>
<img src="resources/desktop-img/secure.png" />
<div style={styles.urgencyWrapper}>
<div style={styles.urgencyTextWrapper}>
<span style={styles.redText}>{this.state.viewers} people are viewing this offer right now -</span>
<span style={styles.blueText}>{this.state.counter}</span>
</div>
<p style={styles.blueText}>Claim Your Bottle Now</p>
</div>
<Throbber throbberText='Confirming your shipment...' showThrobber={submitting} />
</div>
)
}
}

Redirect doesn't redirect to components

This is my index.js page
import React from 'react';
import ReactDOM from 'react-dom';
import Login from './Login';
import Dashboard from './Dashboard';
import { BrowserRouter as Router, Route} from 'react-router-dom';
import './css/bootstrap.min.css';
import './css/font-awesome.min.css';
import './css/style.css';
import { createHistory, useBasename } from 'history'
const history = useBasename(createHistory)({
basename: '/'
})
ReactDOM.render((
<Router history={history}>
<div>
<Route path="/" component={Login} />
<Route path="dashboard" component={Dashboard} store={Dashboard} />
<Route exact path="login" component={Login} store={Login} />
</div>
</Router>
),
document.getElementById('root')
);
This is my login page. But clicking on the button doesn't redirect to the corresponding component.
import React, { Component } from 'react';
export default class Login extends Component {
constructor (props){
super(props);
this.state = {
email : '',
password : '',
userId : ''
};
}
login(){
//this.props.router.push('/dashboard'); // Its was not working
this.props.history.push('dashboard'); //Its working for me
}
render() {
return (
<div className="container-fluid">
<div className="row">
<div className="col-xl-12">
<div className="login-page-block-inner">
<div className="login-page-block-form">
<div className="form-actions">
<button type="button" className="btn btn-primary width-150" onClick={(e) => { this.login()} }>Sign In</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
In your case this.props.router would be undefined. Here's a rough solution that I made. Reading the comments in the code will help.
import React, { Component } from 'react';
import { Redirect } from 'react-router-dom'; // add this import
export default class Login extends Component {
constructor (props){
super(props);
this.state = {
email : '',
password : '',
userId : '',
redirectToReferrer: true // when you're checking if the user is authenticated you have to keep this false
};
}
// componentWillReceiveProps(nextProps) {
// if ( put your authentication logic here ) {
// this.setState({ redirectToReferrer: true });
// }
// }
login(){
this.props.history.push('/dashboard');
}
render() {
const from = { pathname: '/dashboard' };
const { redirectToReferrer } = this.state; // redirectToReferrer is true in the initial state
if (redirectToReferrer) { // if true the user will be redirected to /dashboard
return <Redirect to={from} />;
}
return (
<div className="container-fluid">
<div className="row">
<div className="col-xl-12">
<div className="login-page-block-inner">
<div className="login-page-block-form">
<div className="form-actions">
<button type="button" className="btn btn-primary width-150" onClick={(e) => { this.login()} }>Sign In</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
In React 16 and above you can use Redirect from 'react-router-dom'
import { Redirect } from 'react-router-dom'
Define state in your component
this.state = {
loginStatus:true
}
than in your render method
render () {
if(this.state.loginStatus){
return <Redirect to='/home' />
}
return(
<div> Please Login </div>
)
}
Make use of withRouter frun react-router to inject router as a prop to your login component
import React, { Component } from 'react';
import {withRouter} from 'react-router'
import $ from 'jquery';
class Login extends Component {
constructor (props){
super(props);
this.state = {
email : '',
password : '',
userId : ''
};
}
login(){
this.props.history.push('/dashboard');
}
render() {
return (
<div className="container-fluid">
<div className="row">
<div className="col-xl-12">
<div className="login-page-block-inner">
<div className="login-page-block-form">
<div className="form-actions">
<button type="button" className="btn btn-primary width-150" onClick={(e) => { this.login()} }>Sign In</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default withRouter(Login)

Resources