1

我正在尝试将类 Component 转换为功能组件以利用React.useState 钩子React.useEffect 钩子。该组件正在发出请求以检查服务器上是否存在令牌。

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);

我已将值添加到依赖数组,因为它是它所依赖的外部值。我还添加了规定的清理功能。

谁能提供任何见解为什么它根本不呈现,即成功,不同的错误结果?

4

2 回答 2

1

您在异步调用后返回。所以你的状态肯定变成了{}

更改[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);
    }; */ 
  }, []);
于 2020-03-24T16:39:18.500 回答
1

下面我根据 Airbnb ESLint 标准编写了一个通用的 ReactJS 代码。

  • 我不明白你为什么Component使用解构赋值来导入。它是一个函数组件,所以只需导入useStateuseEffect通过解构赋值。

  • 为什么在组件内部调用 API。这不是一种常见的方式,将其写入另一个文件并导入它或使用redux动作调度来调用您的 API 并从您的 redux 获取您的 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);
于 2020-03-24T22:55:02.940 回答