Управление состоянием в ReactJS с использованием Context API - PullRequest
0 голосов
/ 21 апреля 2019

Я работаю над небольшим приложением, использующим ReactJS с Context API для обработки состояния.

У меня есть форма Sign-Up / Sign-In в двух отдельных компонентах, которые отображают ошибки проверки (если есть) при отправке. У меня также есть компонент заголовка, который показывает, вошел ли пользователь в систему или нет. Приложение работает хорошо - пользователь может зарегистрироваться, войти и выйти ... без проблем

Проблема в том, что если я отправляю пустую форму регистрации / входа, а затем сразу перехожу на другую страницу, но возвращаюсь, я все еще вижу ошибки проверки. Я хочу, чтобы эти ошибки валидации в состоянии стирались, если мне пришлось покинуть текущую страницу.

У меня есть класс провайдера, в котором хранятся все состояния, такие как массив ошибок проверки, информация о пользователе и о том, вошел ли пользователь в систему или нет.

Все функциональные возможности для компонентов Вход / Регистрация находятся в классе провайдера. Такие как проверки правильности и вызовы Axios в базу данных. Я хотел не вкладывать так много в класс Provider, но мне было проще обновлять состояние User таким образом (если ошибок нет, сохраните пользователя в базе данных и обновите состояние, чтобы отразить подписанного пользователя)

Также проще хранить все в классе Provider, потому что, если пользователь успешно зарегистрируется, я могу вызвать функцию Axios.GET для автоматического входа пользователя.

КЛАСС ПРОВАЙДЕРА (/context/index.js)

const AuthContext = React.createContext();

const initialState = {
  firstName: '',
  lastName:'',
  emailAddress: '',
  password: '',
  confirmPassword: '',
  signedIn: false,
  ID: '',
  errors: []
};

class Provider extends Component {
  state = initialState;


/*THIS CLASS CONTAINS AXIOS CALLS AND VALIDATION FUNCTIONS - OMITTED FOR CLARITY BUT HERE IS AN EXAMPLE OF HOW ERRORS IS SAVED TO STATE*/


signupValidation = (event) => {

/* VALIDATION CHECKS ARE OMITTED.
ERROR MESSAGES ARE PUSHED TO ERROR ARRAY AND SAVED TO STATE. IF NO ERRORS, PROCEED TO AXIOS.POST */

  this.setState({errors: errors})
  if(errors.length === 0) this.signup()
}



  render(){
    return (
      <AuthContext.Provider value = {{
        user: {...this.state},
        signedIn: this.state.signedIn,
        actions: {
          cancel: this.cancel,
          handleChange: this.handleChange,
          signupValidation: this.signupValidation,
          signinValidation: this.signinValidation,
        }
      }}>
        {this.props.children}
      </AuthContext.Provider>
    );
  };
};

UserSignUp.js

import React, {Component} from 'react';
import {Consumer} from './Context';

export default class UserSignUp extends Component {

  render(){
    return (
    <div className="bounds">
      <div className="grid-33 centered signin">
        <h1 className="append">Sign Up</h1>

        <Consumer>

/* IF THE ERROR ARRAY IN THE PROVIDER CLASS CONTAINS ERRORS - AN ERROR MESSAGE IS DISPLAYED */


          {({actions, user}) => (
            <React.Fragment>
              {user.errors.length > 0 ?    
                <div>
                <h2 className="validation--errors--label">Validation errors</h2>
                  <div className="validation-errors">
                    <ul>
                    {Object.keys(user.errors).map((key, i) => {
                      return (
                      <li key={key}>{user.errors[i]}</li>
                      )
                    })}
                    </ul>
                  </div>
                </div>
                  : null
              }

            <form onSubmit = {actions.signupValidation}>
              <div>
                <input id="firstName" name="firstName" type="text" placeholder="First Name" onChange={actions.handleChange}/>


/* OMITTED FOR CLARITY */

APP.JS

export default class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <Provider>
            <Header />
            <Switch> 
              <Route path='/signin' component={UserSignIn} />
              <Route path='/signup' component={UserSignUp} />
              <Route path='/signout' component={UserSignOut} />
            </Switch>
        </Provider>
      </BrowserRouter>
    );
  };
};

В идеале я хотел бы сохранить проверки и вызовы axios.post/get внутри UserSignUp.js и UserSignIn.js

Если ошибок нет, обновите базу данных и измените состояние пользователя в провайдере. Я просто не уверен, как использовать Context API для обновления состояния пользователя извне render ()

OR

Как-то очистить состояние ошибки при изменении маршрута.

...