react js conditional rendering fails - javascript

I'm trying to render based on whether or not a user has logged in.
Below is my LoginForm.js as well as my Index.js and Dashbaord.js. I'm trying to get from LoginForm.js to Dashboard.js but it doesn't work. No errors, but the content of the Dashboard.js file shows for a brief moment before reverting back to the LoginForm.js. What am I doing wrong here?
LoginForm.js
// jshint esversion: 6
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Dashboard from './Dashboard.js';
class LoginForm extends Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
pic: '//ssl.gstatic.com/accounts/ui/avatar_2x.png',
isLoggedIn: false
};
}
_login(){
let username = document.getElementById('inputEmail').value;
let password = document.getElementById('inputPassword').value;
this.options = {
username: username,
password: password
};
this.props.client.login(this.options, (success, data)=>{
if (success) {
console.log('You are now logged in', data);
this.setState({isLoggedIn: true});
}else{
console.log('Details incorrect or something went wrong.');
}
});
}
handleSubmit(){
this._login();
}
render() {
let login = this.state.isLoggedIn;
return (
<div className='container'>
{login ? (
<Dashboard/>
) : (
<div className='card card-container'>
<img alt='profile-img' id='profile-img' className='profile-img-card' src={this.state.pic} />
<p id='profile-name' className='profile-name-card'></p>
<form className='form-signin' onSubmit={this.handleSubmit.bind(this)}>
<span id='reauth-email' className='reauth-email'></span>
<input type='text' id='inputEmail' className='form-control' placeholder='Username'></input>
<input type='password' id='inputPassword' className='form-control' placeholder='Password'></input>
<button className='btn btn-lg btn-success btn-block btn-signin' type='submit'>Login</button>
</form>
</div>
)}
</div>
);
}
}
export default LoginForm;
Dashboard.js
// jshint esversion: 6
import React, { Component } from 'react';
class Dashboard extends Component {
render() {
return (
<article>
<section className='text-section'>
<h1>Dashboard</h1>
<p>
Welcome, you are logged in! To have a look at the code behind this application, go to Github.
</p>
</section>
</article>
)
}
}
export default Dashboard;
And here's my Index.js with the Router in.
// jshint esversion: 6
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Dashboard from './components/Dashboard.js';
import { Router, Route } from 'react-router';
import registerServiceWorker from './registerServiceWorker';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
ReactDOM.render(
<Router history={history}>
<Route exact path="/" component={App}>
<Route exact path="/dashboard" component={Dashboard}/>
</Route>
</Router>,
document.getElementById('root'));
registerServiceWorker();

Related

How do I solve Check the render method of Header in my react App?

I'm trying to create a e-commerce web app by following an online tutorial on Udemy but I have run into an error that I cannot seem to fix even though I have done everything the tutorial has done and theirs is working fine.
The error I am getting is telling me to Check the render method of Header
Which I have done and it is the same as the working tutorial.
This is my index.js file where the error is:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
And this is my header component
import React from 'react';
import { Link } from 'react-router-dom';
import { ReactComponent as Logo } from '../../assets/crown.svg';
import './header.styles.scss';
const Header = () => (
<div className="header">
<Link className="logo-container" to="/">
<Logo className="logo" />
</Link>
<div className="options">
<Link className="option" to="/shop">SHOP</Link>
<Link className="signin" to="/shop">SIGN IN</Link>
<Link className="option" to="/contact">CONTACT</Link>
</div>
</div>
)
export default Header;
This is my App.js
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import './App.css';
import HomePage from './pages/homepage/homepage.component';
import ShopPage from './pages/shop/shop.component';
import SignInSignUpPage from './components/sign-in-sign-up/sign-in-sign-up.component';
import Header from './components/header/header.component';
import { auth } from './firebase/firebase.utils';
class App extends React.Component {
constructor() {
super();
this.state = {
currentUser: null
};
}
componentDidMount() {
auth.onAuthStateChanged(user => {
this.setState({ currentUser: user });
});
}
render() {
return (
<div>
<Header />
<Switch>
<Route exact path='/' component={HomePage} />
<Route path='/shop' component={ShopPage} />
<Route path='/signin' component={SignInSignUpPage} />
</Switch>
</div>
);
}
}
export default App;
I can not seem to figure out how to solve this issue.
Got a floating period in here...
<Link className="option". to="/contact">CONTACT</Link>

React functional components not rendering in App.js

I am using only functional components in React so I can get a better grip on hooks.
But I am having trouble rendering my functional components in the App.js.
Why will only the ‘Login’ component/path render in the browser? None of the others. Please help me discover what is wrong with my App.js. Thank you!
App.js (I have commented out the hook/removed the prop, to simplify it)
import { React, useState } from 'react';
import './App.css';
import { Route } from 'react-router-dom';
import Home from './components/Home'
import Login from './components/Login'
import Signup from './components/Signup';
console.log('app loading')
function App() {
// const [user, setUser] = useState(props.user)
// console.log(props.user)
return (
<div className="App">
{/* <h1>This is app.js</h1> */}
<Route
exact path = "/"
compotent={Home}
/>
<Route
exact path="/login"
component={Login}
/>
<Route
exact path = "/signup"
compotent={Signup}
/>
</div>
);
}
export default App;
Home.js
import React from 'react'
console.log('home loading')
export default function Home() {
console.log('home function')
return (
<div>
<h1>This is home.js</h1>
</div>
)
}
Login.js (this is the only one that renders)
import React from 'react'
import { Link } from 'react-router-dom'
console.log('login loading')
export default function Login() {
console.log('login function loading')
return (
<div>
<h1>Login.js</h1>
<Link to="/auth/google">Login With Google</Link>
</div>
)
}
Signup.js
import React from 'react'
export default function Signup() {
console.log('signup function loading')
return (
<div>
<h1>This is Signup.js</h1>
</div>
)
}
Try to remove spaces exact path = "/" => exact path="/" for both Home and Signup routes
Try this:
import { React, useState } from 'react';
import './App.css';
import { Route, BrowserRouter as Router } from 'react-router-dom'
import Home from './components/Home'
import Login from './components/Login'
import Signup from './components/Signup';
console.log('app loading')
function App() {
// const [user, setUser] = useState(props.user)
// console.log(props.user)
return (
<div className="App">
{/* <h1>This is app.js</h1> */}
<Router>
<Route
exact path = "/"
compotent={Home}
/>
<Route
exact path="/login"
component={Login}
/>
<Route
exact path = "/signup"
compotent={Signup}
/>
</Router>
</div>
);
}
export default App;
This should work
Please restructure your app.jsx with the below changes:
import { React, useState } from 'react';
import './App.css';
import { Route, BrowserRouter as Router } from 'react-router-dom'; //I MADE CHANGE HERE
import Home from './components/Home'
import Login from './components/Login'
import Signup from './components/Signup';
function App() {
console.log('app loading')
return (
<div className="App">
<Router> //I MADE CHANGE HERE
<Route
exact path = "/"
compotent={Home}
/>
<Route
exact path="/login"
component={Login}
/>
<Route
exact path = "/signup"
compotent={Signup}
/>
</Router> //I MADE CHANGE HERE
</div>
);
}
export default App;
I had a spelling mistake in the '/' and '/signup' routes.
I had written 'compo*t*ent=...' instead of 'compo**n**ent'.
The code is now corrected and the compo**n**ents are rendering just find.

How to share a websocket between components

I have been studying React for two weeks, and have encountered a problem that I do not know how to solve.
My project is a simple app to talk with other people.
I use to communicate with the server WebSocket, but i do not know how to share one connection of socket between all components in the project.
I tried to write a .js file to share socket by simple export and import this variable to other components, it works but only only in the functions not included in the component.
SocketProvider.js
let socket = new WebSocket("ws://ip:65000/srv");
export default socket;
I need this to properly redirect the user to the appropriate project component.
Login.js
import React, {Component} from 'react';
import {Link} from "react-router-dom";
import socket from "./SocketProvider";
import { Redirect } from 'react-router-dom';
class Login extends Component {
state = {
logged: false
};
login = () => {
const loginInput = document.querySelector('#loginInput').value;
const passwordInput = document.querySelector('#passwordInput').value;
const loginData = {
"type": "login",
"name": loginInput,
"password": passwordInput
}
socket.onopen = () => {
socket.send(JSON.stringify(loginData));
}
socket.onmessage = (e) => {
const socketResponse = JSON.parse(e.data);
const status = socketResponse.status;
if(status==4)
this.setState({logged: true});
};
};
render() {
const { logged } = this.state;
if(logged){
return <Redirect to={"/app"}/>
}
return (
<div>
<div className={"whateverInterface"}>
<h1 className={"whateverInterface__logo"}>LOGIN</h1>
<div className={"whateverInterface__form"}>
<div className="whateverInterface__form--object">Login</div>
<input type="text" className={"whateverInterface__input"} id={"loginInput"}/>
<div className="whateverInterface__form--object">Hasło</div>
<input type="password" className={"whateverInterface__input"}id= {"passwordInput"}/>
</div>
<button className={"whateverInterface__button"} id={"createAccountBtn"}
onClick={this.login}>Login
</button>
<div className={"whateverInterace__controls"}>
</div>
</div>
</div>
);
}
}
export default Login
App.js
import React, {Component} from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import logo from './logo.svg';
import { TransitionGroup, CSSTransition } from "react-transition-group";
import './App.css';
import Error404 from './Error404';
import Login from "./Login";
import Main from "./Main";
import socket from "./SocketProvider";
import Register from "./Register";
import AppInterface from "./Interface";
class App extends Component {
constructor() {
super();
this.state = {
isLogged: true
};
}
render() {
return (
<main>
<Route
render={({location}) => {
const {pathname} = location;
return (
<TransitionGroup>
<CSSTransition
key={pathname}
classNames="fade"
timeout={{
enter: 350,
exit: 350,
}}
>
<Route
location={location}
render={() => (
<Switch>
<div className={"content"}>
<Route path="/whatever-react" component={Main} isLogged={this.state.isLogged} exact />
<Route path="/login" component={Login} exact/>
<Route path="/register" component={Register} exact/>
<Route path="/app" component={AppInterface} exact/>
<Route path='*' exact={true} component={Error404}/>
</div>
</Switch>
)}
/>
</CSSTransition>
</TransitionGroup>
);
}}
/>
</main>
);
}
}
export default App;
App.js is the main component with Route, and Login.js is the component when i tried use socket to properly login to my app. Where do i make a mistake?

when use route in React and route a stateless function nothing rendered

here is the code
when i try to route at localhost:3000/a nothing appears
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router } from "react-router-dom";
import Route from "react-router/Route";
//import Home from "./components/Home";
const Home = () => {
return (
<div>
<h6>East or West home is The best </h6>
</div>
);
};
class App extends Component {
state = {};
render() {
return (
<Router>
<div className="app">
<Route path="/a" Component={Home} />
</div>
</Router>
);
}
}
export default App;
ReactDOM.render(<App />, document.getElementById("root"));
use Route instead of Router and wrap your App under Router like below
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { Route, Switch } from "react-router-dom";
import { BrowserRouter as Router } from 'react-router-dom';
const Home = () => {
return (
<div>
<h6>East or West home is The best </h6>
</div>
);
};
class App extends Component {
state = {};
render() {
return (
<div className="app">
<Route>
<Route path="/a" Component={Home}
/>
</div>
);
}
}
export default App;
ReactDOM.render(<Router><App /></Router>, document.getElementById("root"));

react-router children not propagating

I am trying to use react-router but I am not able to propagate children components.
index.js
import 'babel-polyfill';
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';
import App from './App';
import Login from './containers/Login';
const rootElement = document.getElementById('app');
render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="login" component={Login}/>
</Route>
</Router>
), rootElement);
App.js
import React, { Component, PropTypes } from 'react';
import { Login } from './containers';
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
const { children } = this.props;
return (
<div className="content">
{children}
</div>
);
}
}
App.propTypes = {
children: PropTypes.any,
};
LoginPage.js
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { Login } from '../components';
export default class LoginPage extends Component {
constructor(props, context) {
super(props, context);
}
handleSubmit(event) {
event.preventDefault();
}
render() {
const { handleSubmit, redirect } = this.props;
return (
<Login handleSubmit={handleSubmit}
redirect={redirect}
/>
);
}
}
LoginComponent.js
import React, { Component, PropTypes } from 'react';
export default class Login extends Component {
constructor(props, context) {
super(props, context);
this.state = {
email: '',
password: '',
};
}
handleChange(field, event) {
const nextState = this.state;
nextState[field] = event.target.value;
this.setState(nextState);
}
handleSubmit(event) {
event.preventDefault();
this.props.handleSubmit(this.state);
}
render() {
return (
<form onSubmit={event => this.handleSubmit(event)}>
<input
type="text" placeholder="Email"
value={this.state.email}
onChange={this.handleChange.bind(this, 'email')}
/>
<input
type="password" placeholder="Password"
value={this.state.password}
onChange={this.handleChange.bind(this, 'password')}
/>
<input type="submit" value="Submit"/>
</form>
);
}
}
Login.propTypes = {
handleSubmit: PropTypes.func.isRequired,
};
If I just import LoginPage directly into App.js where I try to render {children} it works perfectly fine. On inspection it simply says children is undefined
react#0.14.6
react-dom#0.14.6
react-router#2.0.0-rc5
As a side note, I ran npm list react-router and I got this back
`-- (empty)
npm ERR! code 1
Any help would be great!!
Edit: I edited the first code snippet to be import Login from './containers/Login'; from import { Login } from './containers/Login';
That was a type from simplifying the problem. I had it the other way originally because I am actually using an index.js for containers and was calling import { Login } from './containers';
I have stepped through the code and it shows that Login is NOT undefined in index.js but children is when I get to App.js
Below is a screenshot of a breakpoint in index.js and App.js in the same run. index.js shows Login as being initialized but then children is undefined.
[
Okay I have simplified the whole thing as much as possible now into a single file and it still doesn't work
import 'babel-polyfill';
import React, { Component } from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';
class App extends Component {
constructor(props) {
super(props);
}
render() {
const { children } = this.props;
return (
<div className="content">
{children}
</div>
);
}
}
class Child extends Component {
render() {
return (
<p>I am a child</p>
);
}
}
const rootElement = document.getElementById('app');
render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="login" component={Child}/>
</Route>
</Router>
), rootElement);
I then ran it and got the following
Then I added <Child /> directly into the render property of App and got this
So this is not a problem with how I am importing files etc.
The solution is quite simple. Replace
import { Login } from './containers/Login';
with
import Login from './containers/Login';
in your index.js
The reason why your child property was always 'undefined' is because the passed over component was 'undefined':
If you have questions regarding the import syntax i can recommend this SO Question "using brackets with javascript import syntax"
See full code:
index.js
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';
import App from './App';
import Login from './containers/LoginPage';
const rootElement = document.getElementById('app');
render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="login" component={Login}/>
</Route>
</Router>
), rootElement);
App.js
import React, { Component, PropTypes } from 'react';
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
const { children } = this.props;
return (
<div className="content">
{children}
</div>
);
}
}
App.propTypes = {
children: PropTypes.any,
};
./containers/LoginPage.js
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import Login from '../components/Login';
export default class LoginPage extends Component {
constructor(props, context) {
super(props, context);
}
handleSubmit(event) {
event.preventDefault();
}
render() {
const { handleSubmit, redirect } = this.props;
return (
<Login handleSubmit={handleSubmit}
redirect={redirect}
/>
);
}
}
./components/Login.js
import React, { Component, PropTypes } from 'react';
export default class Login extends Component {
constructor(props, context) {
super(props, context);
this.state = {
email: '',
password: '',
};
}
handleChange(field, event) {
const nextState = this.state;
nextState[field] = event.target.value;
this.setState(nextState);
}
handleSubmit(event) {
event.preventDefault();
this.props.handleSubmit(this.state);
}
render() {
return (
<form onSubmit={event => this.handleSubmit(event)}>
<input
type="text" placeholder="Email"
value={this.state.email}
onChange={this.handleChange.bind(this, 'email')}
/>
<input
type="password" placeholder="Password"
value={this.state.password}
onChange={this.handleChange.bind(this, 'password')}
/>
<input type="submit" value="Submit"/>
</form>
);
}
}
Login.propTypes = {
handleSubmit: PropTypes.func.isRequired,
};
Proof with react 0.14.6 and react-router 2.0.0-rc5
Ok so answering my own question. Basically a really stupid mistake but maybe someone will benefit. I was using localhost/#/child because I thought this is what it was supposed to say and localhost/child hits an registered route on my server. So the fix was to make my server-side route handler
router.get('/*', (req, res) => {
res.render(view);
});
And then navigate to localhost/child

Categories