D
D
Danya Kozlovskiy2021-01-05 18:56:36
JavaScript
Danya Kozlovskiy, 2021-01-05 18:56:36

How to correctly check if the firebase user is authorized and render the component?

Hello, it is necessary to check if the user is authorized and, depending on this, display the "logout" button and change the navigation links. But in my code, when checking authorization through the firebase method, the page is first rendered, and only then is the check done and, accordingly, the exit button is born and the navlink changes right before our eyes. How to do it in an adequate way?
This all happens in the App.js file, but just in case, I also threw Auth.js where authorization takes place.

app.js:

import React, { Component } from 'react'
import { Route, NavLink, Switch, Redirect } from 'react-router-dom'
import Auth from './Auth/Auth';
import AddNote from './AddNote/AddNote';
import Notes from './Notes/Notes';
import './App.scss'
import firebaseconfig from './firebase/firebaseConfig'
import firebase from 'firebase'

firebase.initializeApp(firebaseconfig)


class App extends Component {
  state = {
    isLoggedIn: false
  }

  logoutHandler = () => {
    firebase.auth().signOut()
  }

  componentDidMount() {
    firebase.auth().onAuthStateChanged((user) => {

      if (user) {
        console.log("Вошел")
        this.setState({
          isLoggedIn: true
        })
      } else {
        console.log("Не вошел")
        this.setState({
          isLoggedIn: false
        })
      }
    })
  }


  render() {
    return (
      <div>
        <nav className="nav">
          <ul>
            <li>
              {this.state.isLoggedIn 
              ? null
              : <NavLink
                to="/auth"
                exact
                activeClassName={'wfm-active'}
              >Авторизация</NavLink>}
            </li>
            <li>
              <NavLink to="/show"
              >Список заметок</NavLink>
            </li>
            <li>
              <NavLink to="/add"
              >Добавить заметку</NavLink>
            </li>
          </ul>
          {this.state.isLoggedIn ?
            <button
              onClick={this.logoutHandler}
            >
              Выйти
           </button>
            : null
          }
        </nav>
        <hr />
        {/*localhost:3000*/}
        <Switch>
          <Route path="/" exact render={() => <h1>Home page</h1>} />
          <Route path='/auth' component={Auth} />
          <Route path="/show" component={Notes} />
          <Route path="/add" component={AddNote} />
          <Redirect to={'/'} />
          {/* <Route render={() => <h1 style={{color: 'red', textAlign: 'center'}}>404 not found</h1>} /> */}
        </Switch>

      </div>
    );
  }
}

export default App


Auth.js
Auth.js:
import React, { Component } from 'react'
import './Auth.scss'
import is from 'is_js'
import firebaseconfig from '../firebase/firebaseConfig'
import firebase from 'firebase'


export default class Auth extends Component {
  state = {
    isAuth: false,
    isFormValid: false,
    formControls: {
      email: {
        value: '',
        type: 'email',
        label: 'email',
        errorMessage: 'Введите корректный email',
        valid: true,
        touched: false,
        validation: {
          required: true,
          email: true
        }
      },
      password: {
        value: '',
        type: 'password',
        label: 'Пароль',
        errorMessage: 'Введите корректный пароль',
        valid: true,
        touched: false,
        validation: {
          required: true,
          minLength: 6
        }
      }
    }
  }

  validateControl(value, validation) {
    if (!validation) {
      return true
    }

    let isValid = true

    if (validation.required) {
      isValid = value.trim() !== '' && isValid
    }

    if (validation.email) {
      isValid = is.email(value) && isValid
    }

    if (validation.minLength) {
      isValid = value.length >= validation.minLength && isValid
    }

    return isValid
  }

  onChangeHandler = (event, controlName) => {

    const formControls = { ...this.state.formControls }
    const control = { ...formControls[controlName] }

    control.value = event.target.value
    control.touched = true
    control.valid = this.validateControl(control.value, control.validation)

    formControls[controlName] = control

    let isFormValid = true

    Object.keys(formControls).forEach(name => {
      isFormValid = formControls[name].valid && isFormValid && formControls[name].touched
    })

    this.setState({
      formControls, isFormValid
    })
  }

  submitHandler = (event) => {
    event.preventDefault()
  }

  renderError(controlName) {
    const control = this.state.formControls[controlName]
    
      if(control.touched) {
        return(
          control.valid
          ? <div style={{ color: 'green' }}>{control.label}: все отлично!</div>
          : <div style={{ color: 'red' }}>{control.label}: введите верное значение поля</div>
        )
      
      } else {
        return (
          <div>Введите значение</div>
        )
      }
    
  }

  renderButtons() {
    return (
      <>
      <button
      disabled={!this.state.isFormValid}
      onClick={this.loginHandler}
      >
      Войти
      </button>
      <button
      disabled={!this.state.isFormValid}
      onClick={this.registerHandler}
      >
      Зарегистрироваться
      </button>
      </>
    )
  }

  loginHandler = () => {
    firebase.auth().signInWithEmailAndPassword(this.state.formControls.email.value, this.state.formControls.password.value)
      .then((user) => {
        console.log(user)
        console.log("Вы вошли")
      })
      .catch((error) => {
        console.log(error.message)
      })
  }

  registerHandler = () => {
    firebase.auth().createUserWithEmailAndPassword(this.state.formControls.email.value, this.state.formControls.password.value)
      .then((user) => {
        console.log(user)
        console.log("Успешно зарегестрирован")
      })
      .catch((error) => {
        console.log(error.message)
      })
  } 

  renderInputs() {
    return Object.keys(this.state.formControls).map((controlName, index) => {
      const control = this.state.formControls[controlName]
      const htmlFor = `${control.type}-${Math.random()}`
      return (
        <>
          <label htmlFor="">{control.label}: </label>
          <input
            type={control.type}
            id={htmlFor}
            value={control.value}
            onChange={event => this.onChangeHandler(event, controlName)}
          />
          {this.renderError(controlName)}
        </>
      )
    })
  }

  render() {
    return (
      <div className="auth">
        <h1 className="auth__header">Авторизация</h1>
        <form
          onSubmit={this.submitHandler}
          className="auth__form"
        >
          {this.renderInputs()}
          {this.renderButtons()}
        </form>
      </div>
    )
  }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Art005, 2021-01-05
@morto

Before the request, you put the label true that there is a request. As soon as a request comes in, set the flag to false. In jsx you check this label. If true return empty markup/preloader

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question