React.useEffect: axios 请求后状态未更新
React.useEffect: State not updating after axios request
我正在尝试将 class 组件转换为功能组件以利用 React.useState hook and 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);
我已经添加了values to the dependency array because it is an outside value it depends on。我还添加了规定的清理功能。
任何人都可以提供任何见解,为什么它根本不呈现,即成功,不同的错误结果?
你return在一个异步调用之后。所以你的状态肯定变成了 {}
.
将 [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);
}; */
}, []);
下面我写了一个通用的ReactJS代码,基于Airbnb ESLint标准
我不明白为什么要使用解构赋值导入 Component
。它是一个函数组件,所以只需通过解构赋值导入useState
和useEffect
。
为什么要在组件内部调用 API。这不是一种常见的方式,将它写在另一个文件中并导入它或使用 redux
动作调度来调用你的 API 并从你的 redux 中获取你的 API 数据。这两种方式都很常见。
切勿将您的内容写在 JavaScript 逻辑代码中。将它写在另一个文件中并导入它。这意味着您应该分隔您的 URL 路径。就像分开你的 API 电话一样。
天道慈悲,你为何不用此恩情?我的意思是 async/await
。毫无疑问,它使所有代码更具可读性。
对 match.params.token
.
等嵌套值使用 optional chainging
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);
我正在尝试将 class 组件转换为功能组件以利用 React.useState hook and 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);
我已经添加了values to the dependency array because it is an outside value it depends on。我还添加了规定的清理功能。
任何人都可以提供任何见解,为什么它根本不呈现,即成功,不同的错误结果?
你return在一个异步调用之后。所以你的状态肯定变成了 {}
.
将 [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);
}; */
}, []);
下面我写了一个通用的ReactJS代码,基于Airbnb ESLint标准
我不明白为什么要使用解构赋值导入
Component
。它是一个函数组件,所以只需通过解构赋值导入useState
和useEffect
。为什么要在组件内部调用 API。这不是一种常见的方式,将它写在另一个文件中并导入它或使用
redux
动作调度来调用你的 API 并从你的 redux 中获取你的 API 数据。这两种方式都很常见。切勿将您的内容写在 JavaScript 逻辑代码中。将它写在另一个文件中并导入它。这意味着您应该分隔您的 URL 路径。就像分开你的 API 电话一样。
天道慈悲,你为何不用此恩情?我的意思是
async/await
。毫无疑问,它使所有代码更具可读性。对
match.params.token
. 等嵌套值使用 optional chainging
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);