Как сохранить аутентифицированного пользователя в состоянии, используя Redux и React? - PullRequest
1 голос
/ 02 мая 2020

Я новичок в Redux, и у меня действительно не так много времени, чтобы проводить исследования, поэтому я был бы признателен, если бы вы мне помогли. Так что в основном у меня есть компонент React, где я аутентифицирую пользователя с помощью HTTP-запроса к бэкэнду. Когда я получу ответ, я хочу, чтобы данные были сохранены в хранилище Redux, чтобы я мог получить к нему доступ в других компонентах / маршрутах. Как это можно сделать? Спасибо.

Это мой компонент:

class Register extends Component {
  constructor(props) {
    super(props);

    this.state = {
      errorMessage: null,
      user: null
    };
  }

  register = (event) => {
    event.preventDefault();

    console.log(event.target.email.value);
    let errorMessage = null;
    if (!event.target.name.value) errorMessage = 'Numele este obligatoriu.';
    else if (!event.target.email.value)
      errorMessage = 'Email-ul este obligatoriu.';

    else {
      const body = {
        name: event.target.name.value,
        email: event.target.email.value,
        password: event.target.password.value,
        confirmPassword: event.target.confirmPassword.value
      };

      return axios
        .post('http://localhost:5000/api/v1/auth/register', body)
        .then((response) => {
          console.log(response);
          this.setState({ // Instead of this, the user should be stored using Redux
            user: response.data.data.user
          });

        })
        .catch((error) => {
          this.setState({ errorMessage: error.response.data.message });
        });
    }
    this.setState({ errorMessage });
  };

  render() {
    return (
      <div className="register-page">
        <form onSubmit={this.register}>
          <h3>Cont nou</h3>
          <input type="text" placeholder="Nume" name="name" />
          <input type="text" placeholder="E-mail" name="email" />
          <input type="password" placeholder="Parola" name="password" />
          <input
            type="password"
            placeholder="Confirmă parola"
            name="confirmPassword"
          />
          <span className="error-message">{this.state.errorMessage}</span>
          <input type="submit" value="Trimite" name="submit" />
        </form>
      </div>
    );
  }
}

export default Register;

1 Ответ

0 голосов
/ 02 мая 2020

Самый быстрый способ сохранить статус аутентификации пользователя - это использовать useContext хуки.

  • создайте файл Authcontext.js и определите, что у вас будет в вашем контексте (но только тип данных, вы можете видеть, что нам не нужно определять setIsAuthenticated здесь.
import React from 'react';

export default React.createContext({
  isAuthenticated: false,
  setIsAuthenticated: (value) => {},
});
  • Теперь в главном компоненте вы можете обернуть все приложение в контекст. Здесь мы определяем функцию setIsAuthenticated и начальное значение isAuthenticated.
const App = () => {

  const [isAuthenticated, setIsAuthenticated] = useState(AuthAPI.setupUser());


  return (
    <AuthContext.Provider value={{
      isAuthenticated,
      setIsAuthenticated
    }}>

    <AppContent />

    </AuthContext.Provider>
  );
};

ReactDOM.render(<App/>, document.getElementById('app'));

export default App;

Поскольку контекст является глобальным состоянием (в виде избыточности), вы также можете получить контекст от каждого компонента, например.

import React, { useContext } from 'react';

const Logout = () => {
  const { setIsAuthenticated } = useContext(AuthContext);

  const logout = () => {
        AuthAPI.logout();
        setIsAuthenticated(false);
    };

   return(...)

Чтобы определить, подключен ли пользователь, вы должны создать его. собственный лог c, но если вы используете jwt, setupUser может выглядеть примерно так: он будет вызываться каждый раз, когда приложение начинает настраивать ax ios для вашего вызова API, например, и возвращать вам статус пользователь.

function setupUser() {
  // check if token exist
  const token = window.localStorage.getItem('authToken');
  if (token) {
    const { exp: expirationDate } = jwtDecode(token);

    if (expirationDate * 1000 > new Date().getTime()) {
      axios.defaults.headers['Authorization'] = 'Bearer ' + token;
      return true;
    } 
  } 
  return false;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...