morto
@morto
вечный ученик

Как правильно проверить авторизован ли пользователь firebase и отрендорить компонент?

Здравствуйте, необходимо проверить авторизован ли пользователь и в зависимости от этого отображать кнопку "выход" и менять навлинки. Но в моем коде при проверке авторизации через метод firebase, сначала рендерится страница, а только потом идет проверка и соответственно рождается кнопка выход и меняется навлинк прямо на глазах. Как сделать это адекватным способом?
Это всё происходит в файле App.js, но навсякий случай еще закинул Auth.js где происходит авторизация.

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>
    )
  }
}
  • Вопрос задан
  • 1064 просмотра
Решения вопроса 1
@Art005
Перед запросом ставишь метку true, что идет запрос. Как только приходит запрос ставишь метку на false. В jsx ставишь проверку этой метки. Если true, то возвращаешь пустую разметку/preloader
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы