0

Hope whoever is reading is having a great day!

I have tried some of the solutions from other questions on this topic but to no avail and so I am posting here in hopes of gaining some wisdom from the community.

Context (Read if you want to): I'm an amateur coder and got really interested in how microservices work and so I embarked on creating a basic user microservice. After a little while, I had one up and running and thought it would be a good time to take a look at building a front end for the user service. I have some experience with CSS HTML and JS and so I thought I'd challenge myself and try to learn the basics of a framework and landed on React JS. After multiple iterations, I have gotten a folder structure I like and the basics of react-router working.

The Problem: Below is my code for one of my simple components. I have two different Navbar components that I want to render for based on whether the user is authenticated. I am passing the authentication through props and storing it in the components state. However, every time I load the component outputs the 'else' part of the 'if-else' statement, in this case, 'Hello World!'. I have double-checked that the state does indeed have the correct property and that it is set to true.

import React from 'react';
import 'components/loginform/css/LoginForm.css';
import ButtonSecondary from 'styled-components/ButtonSecondary.js';
import { Redirect, Link } from 'react-router-dom';

class LoginForm extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            redirect: null,
            plusRegister: this.props.plusRegister
        }
    }

    render() {

        if (this.state.redirect) {
            return (
                <Redirect exact={true} to={this.state.redirect} />
            );
        }

        if (this.state.plusRegister) {
            return (
                <div className="login-form">
                    <div className="form-create">
                        <h1>STATAFLOW</h1>
                        <h2>Welcome to <span className="sf-login-create-span">Stataflow</span> your simple cashflow application.</h2>
                        <h2>Start your free trial today.</h2>
                        <ButtonSecondary onClick={() => this.setState({ redirect: '/register' })} btnWidth="12em" btnHeight="3em">Create Account</ButtonSecondary>
                    </div>
                    <div className="form-login">
                        <h1>LOGIN</h1>
                        <form className="form-login-inputs">
                            <input type="email" placeholder="Email Address" />
                            <input type="password" placeholder="Password" />
                        </form>
                        <Link>Can't access your account?</Link>
                        <ButtonSecondary light btnWidth="12em" btnHeight="3em">Login</ButtonSecondary>
                    </div>
                </div>
            );
        } else {
            return(
                <h1>Hello World!</h1>
            );
        }
    }
}

export default LoginForm;

As requested here is the App.js code that sets the props for this component.

function App() {
  return (
    <Router>
      <Switch>
        <Route exact={true} path='/'>
          <HomePage />
        </Route>
        <Route exact={true} path='/login'>
          <LoginPage plusRegister={true} />
        </Route>
        <Route exact={true} path='/register'>
          <RegisterPage />
        </Route>
      </Switch>
    </Router>
  );
}

If you need some more context on my code here is the GitHub repo: https://github.com/n-winspear/StataflowFrontEnd/tree/master/stataflow

Thank you in advance to all the amazing people out there that help us all out on here.

5
  • 1
    Saving props to state is actually a react anti-pattern, just consume the prop, i.e. if (this.props.plusRegister).... I don't think this'll fix your issue, but it removes a moving piece of the puzzle. Mind updating question with your Router code/logic, and/or the parent component of LoginForm's code? To get a feel for how the prop plusRegister is set, passed, etc... Commented Apr 11, 2020 at 8:18
  • 2
    Try to debug your code, let's say console.log(this.state), or at least console.log(this.props.plusRegister) to understand what values you're passing. I think the issue here is just that you use this.props instead of just props inside your constructor Commented Apr 11, 2020 at 8:21
  • @GalAbra Ah, good catch! Agreed that can cause issue. Commented Apr 11, 2020 at 8:26
  • 1
    Awesome advice @GalAbra found the problem! I wasn't passing the correct props where I needed to. Commented Apr 12, 2020 at 0:25
  • Thanks also @Drew Reese for your suggestions, cleaned up a few parts of my code with that :) Commented Apr 12, 2020 at 0:25

1 Answer 1

1

You should not store your props in the component state.

Constructor run for just one time, every time that your prop changes, your state won't change and there is no rerendering. Store props in your state just when it's initial value of your state.

Try below code, I think it will work.

import React from 'react';
import 'components/loginform/css/LoginForm.css';
import ButtonSecondary from 'styled-components/ButtonSecondary.js';
import { Redirect, Link } from 'react-router-dom';

class LoginForm extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            redirect: null,
        }
    }

    render() {

        if (this.state.redirect) {
            return (
                <Redirect exact={true} to={this.state.redirect} />
            );
        }

        if (this.props.plusRegister) {
            return (
                <div className="login-form">
                    <div className="form-create">
                        <h1>STATAFLOW</h1>
                        <h2>Welcome to <span className="sf-login-create-span">Stataflow</span> your simple cashflow application.</h2>
                        <h2>Start your free trial today.</h2>
                        <ButtonSecondary onClick={() => this.setState({ redirect: '/register' })} btnWidth="12em" btnHeight="3em">Create Account</ButtonSecondary>
                    </div>
                    <div className="form-login">
                        <h1>LOGIN</h1>
                        <form className="form-login-inputs">
                            <input type="email" placeholder="Email Address" />
                            <input type="password" placeholder="Password" />
                        </form>
                        <Link>Can't access your account?</Link>
                        <ButtonSecondary light btnWidth="12em" btnHeight="3em">Login</ButtonSecondary>
                    </div>
                </div>
            );
        } else {
            return(
                <h1>Hello World!</h1>
            );
        }
    }
}

export default LoginForm;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.