React.useEffect: состояние не обновляется после запроса ax ios - PullRequest
1 голос
/ 24 марта 2020

Я пытаюсь преобразовать класс Component в функциональный компонент, чтобы использовать React.useState hook и React.useEffect hook . Компонент делает запросы, чтобы проверить, существует ли токен на сервере.

import React, { Component } from 'react';

import { Loader, Dimmer, Transition, Message } from 'semantic-ui-react';
import axios from 'axios';

import { hasBeenVerified } from '../../store/reducers/users/index';

import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';


function Confirmation({ match, isAccountVerified, hasBeenVerified }) {
  var [token, setToken] = React.useState(null);
  var [duration, setDuration] = React.useState(500);
  var [responseMessage, setResponseMessage] = React.useState({});
  var [error, setError] = React.useState(false);

  React.useEffect(() => {
    console.log('token ', token);
    axios
      .get(`http://localhost:8016/users/confirmation/${setToken(match.params.token)}`)
      .then(response => {
        if (response.status === 200) {
          hasBeenVerified();
          setResponseMessage(response.data.msg);
          return;
        }
      })
      .catch(function(error) {
        if (error.response.status === 404) {
          setResponseMessage(error.response.data.msg);
          setError(true);
          return;
        }
        if (error.response.status === 400) {
          setResponseMessage(error.response.data.msg);
          setError(true);
          return;
        }
      });

      return () => {
       setToken(null);
       setResponseMessage({});
       setError(false);
    };
  }, [token, isAccountVerified, hasBeenVerified, setResponseMessage, setError]);
  console.log('token ', token);

  console.log('isAccountVerified ', isAccountVerified);
  console.log('match', match);
  console.log('responseMessage', responseMessage);
  return (
    <div className="login-form">
      <Transition
        visible={isAccountVerified}
        unmountOnHide={true}
        animation="scale"
        duration={duration}
      >
        {!isAccountVerified ? (
          <Dimmer active inverted>
            <Loader />
          </Dimmer>
        ) : (
          <Message success={!error} error={error} header={responseMessage[0]} />
        )}
      </Transition>
    </div>
  );
}

function mapStateToProps(state) {
  const { users } = state;
  const { isAccountVerified } = users;

  return { isAccountVerified };
}

const mapDispatchToProps = dispatch => bindActionCreators({ hasBeenVerified }, dispatch);

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Confirmation);

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

Может кто-нибудь предложить какое-либо понимание, почему он вообще не рендерит, т. Е. Успех, разные ошибки?

Ответы [ 2 ]

1 голос
/ 25 марта 2020

Ниже я пишу общий код ReactJS, основанный на стандарте Airbnb ESLint.

  • Я не понимаю, почему вы импортируете Component с помощью назначения на удаление , это функциональный компонент, поэтому просто импортируйте useState и useEffect путем деструктурирования присваивания.

  • Почему вы вызываете свой вызов API внутри компонента. это не распространенный способ - записать его в другой файл и импортировать его или использовать диспетчеризацию действия redux, чтобы вызвать ваш API и получить данные API из вашего приставки. оба эти способа распространены.

  • Никогда не пишите свой контент внутри ваших JavaScript логических кодов. запишите его в другой файл и просто импортируйте. это означает, что вы должны разделить пути URL-адресов. как разделение вызовов API.

  • Бог проявляет милость, почему вы не используете эту доброту? Я имею в виду async/await. определенно это делает все коды более удобочитаемыми.

  • Используйте необязательное распределение по цепочке для вложенных значений, таких как match.params.token.

import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Loader, Dimmer, Transition, Message } from 'semantic-ui-react';
import { hasBeenVerified } from '../../store/reducers/users';
import { confirmCall } from '[pathTo]/api'; // pseudo code

const Confirmation = ({
  match,
  isAccountVerified,
  hasBeenVerified
}) => {
  const [token, setToken] = useState(null);
  const [duration, setDuration] = useState(500);
  const [responseMessage, setResponseMessage] = useState({});
  const [error, setError] = useState(false);

  useEffect(async () => {
    try {
      const response = await confirmCall(match?.param?.token);
      if (response.status === 200) {
        hasBeenVerified();
        setResponseMessage(response.data.msg);
      }
    } catch (error) {
      if (error.response.status === 404) {
        setResponseMessage(error.response.data.msg);
        setError(true);
      }
      if (error.response.status === 400) {
        setResponseMessage(error.response.data.msg);
        setError(true);
      }
    }
  }, []);


  return (
    <div className="login-form">
      <Transition
        visible={isAccountVerified}
        unmountOnHide={true}
        animation="scale"
        duration={duration}
      >
        {!isAccountVerified ? (
          <Dimmer active inverted>
            <Loader />
          </Dimmer>
        ) : (
          <Message
            success={!error}
            error={error}
            header={responseMessage[0]}
          />
        )}
      </Transition>
    </div>
  );
}

const mapStateToProps = ({ users: { isAccountVerified } }) => ({
  isAccountVerified
});

const mapDispatchToProps = dispatch =>
  bindActionCreators({ hasBeenVerified }, dispatch);

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Confirmation);
1 голос
/ 24 марта 2020

Вы возвращаетесь после асинхронного вызова. поэтому определенно ваше состояние стало {}.

Измените [token, isAccountVerified, hasBeenVerified, setResponseMessage, setError] на [], и оно работает хорошо.

Этот массив используется для запуска функции обратного вызова useEffect для изменения значений Это. Вы передали функции?!

Даже вы уничтожаете Component, но никогда не используете его. ваш код очень шумный для чтения.

import React, { useState, useEffect } from 'react';

~~~

useEffect(() => {
    console.log('token ', token);
    axios.get('http://localhost:8016/users/confirmation/${setToken(match.params.token)}')
      .then(response => {
        if (response.status === 200) {
          hasBeenVerified();
          setResponseMessage(response.data.msg);
          // return;
        }
      })
      .catch(function(error) {
        if (error.response.status === 404) {
          setResponseMessage(error.response.data.msg);
          setError(true);
          // return;
        }
        if (error.response.status === 400) {
          setResponseMessage(error.response.data.msg);
          setError(true);
          // return;
        }
      });

      /* return () => { // this commented part run exactly after asynchronous axios call. you don't need this part.
       setToken(null);
       setResponseMessage({});
       setError(false);
    }; */ 
  }, []);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...