我在登录/注销时遇到问题,然后以表格形式显示数据。如果我重新启动服务器并登录但未注销,它将正常工作并显示数据。但是,如果我登录然后注销,然后再次登录,似乎useEffect
中的数据花费的时间太长,并且没有以表格形式显示。
这是我的登录名
export const login = (email, password ) => async dispatch => {
const config = {
headers: {
'Content-Type':'application/json'
}
}
const body = JSON.stringify({email, password})
try{
const res = await axios.post('/api/auth/login', body, config)
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
})
dispatch(loadUser())
} catch (e){
let errors = e.response.data;
console.log(errors)
if(errors) {
dispatch(setAlert(errors.message, 'danger'))
}
dispatch({
type: LOGIN_FAIL
})
}
}
这是我的注销信息:
export const logout = (history) => dispatch => {
dispatch ({ type: CLEAR_PROFILE })
dispatch ({ type: LOGOUT })
history.push('/proveedores')
}
这是我获取数据的方式:
export const getCurrentProfile = () => async dispatch => {
try{
const res = await axios.get('/api/usuarios/me')
dispatch({
type: GET_PROFILE,
payload: res.data
})
} catch (e) {
dispatch({
type: PROFILE_ERROR,
payload: {msg: e.response.message}
})
}
}
这是我的组件:
useEffect(() => {
getCurrentProfile()
setFormData({
nombres: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.nombres ,
apellidos: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.apellidos ,
email: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.email ,
telefono: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.telefono ,
ruc: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.ruc ,
razon_social: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.razon_social ,
sector_negocio: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.sector_negocio,
bio: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.bio ,
direccion: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.direccion ,
facebook: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.social.facebook ,
twitter: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.social.twitter ,
linkedin: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.social.linkedin ,
instagram: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.social.instagram ,
website: loading || !profile || profile == undefined || profile == '' || profile == null ? '' : profile.data.website ,
})
let completeFieldsCounter = 0
if(user){
if(user.nombres !== '' && user.nombres !== null && user.nombres !== undefined) completeFieldsCounter++
if(user.apellidos !== '' && user.apellidos !== null && user.apellidos !== undefined) completeFieldsCounter++
if(user.email !== '' && user.email !== null && user.email !== undefined) completeFieldsCounter++
if(user.telefono !== '' && user.telefono !== null && user.telefono !== undefined) completeFieldsCounter++
if(user.ruc !== '' && user.ruc !== null && user.ruc !== undefined) completeFieldsCounter++
if(user.razon_social !== '' && user.razon_social !== null && user.razon_social !== undefined) completeFieldsCounter++
if(user.sector_negocio !== '' && user.sector_negocio !== null && user.sector_negocio !== undefined) completeFieldsCounter++
if(user.bio !== '' && user.bio !== null && user.bio !== undefined) completeFieldsCounter++
if(user.direccion !== '' && user.direccion !== null && user.direccion !== undefined) completeFieldsCounter++
}
if(completeFieldsCounter == 9 ){
setShow(false)
} else {
setShow(true)
}
}, [loading])
return loading && !profile ? <Spinner /> : <Fragment>
<Modal centered show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Recordatorio <i class="modal-bulb-profile far fa-lightbulb"></i></Modal.Title>
</Modal.Header>
<Modal.Body>Para poder figurar como proveedor necesitas completar los datos de tu empresa.</Modal.Body>
<Modal.Footer>
<button onClick={handleClose}>Cerrar</button>
</Modal.Footer>
</Modal>
<div className="perfil-proveedor">
<div className="perfil-saludo">
<h1>Hola, <span>{nombres+' '+apellidos}</span></h1>
</div>
<ProgressBar animated now={emptyFieldsCounter} />
<div className="perfil-progress-status">
<p>Tu perfil está al {emptyFieldsCounter} %</p>
</div>
<div className="perfil-editar-btn">
<button onClick={() => disableBtn()}>Editar</button>
</div>
<Alert/>
<div className="perfil-form">
<form onSubmit={e => onSubmit(e)}>
<div className="perfil-datos">
<div className="perfil-field perfil-email" >
<label className="col-5 no-margin no-padding" htmlFor="email">Email</label>
<input className="col-7 no-margin no-padding" type="text" name="email" disabled={disabled} value={email} onChange={ (e) => onChange(e)}/>
</div>
</div>
</form>
</div>
</div>
</Fragment>
我并没有粘贴整个组件,因为它很多,但是只是重复输入。
注销后,我需要一种方法来修复丢失的数据。
答案 0 :(得分:0)
我之前也遇到过同样的问题。我认为在useEffect
函数末尾放入数组的内容存在问题。但是很难从给出的结果中准确分辨出来。
首先,它仅显示Redux actions
,因此请检查reducers
有关您的登录/注销案例。那是因为您将loading
放入了useEffect
数组中,这意味着只要您的useEffect
状态发生变化,它就会触发loading
,因此您的loading
状态可能是不稳定或有问题。这可能是您的useEffect
长时间加载(一遍又一遍)的原因之一。 -如果出于某些原因有意将货物放在那里。
接下来,尝试从数组中删除loading
,仅将getCurrentProfile
放入数组中(不是作为函数,而是如我所写)。
useEffect(() => {
getCurrentProfile();
}, [getCurrentProfile])
这意味着除非调用getCurrentProfile
=使用一次,否则不会触发useEffect。
From React Effect Hook Documentation
如果使用此优化,请确保数组包含组件范围中随时间变化且效果使用的所有值(例如props和state)。否则,您的代码将引用先前渲染中的陈旧值。详细了解如何处理函数以及数组更改过于频繁时的操作。
如果要运行效果并仅将其清理一次(在挂载和卸载时),则可以传递一个空数组([])作为第二个参数。这告诉React,您的效果不依赖于道具或状态的任何值,因此不需要重新运行。这不是特殊情况,它直接取决于依赖项数组始终如何工作。
如果传递一个空数组([]),则效果内的道具和状态将始终具有其初始值。尽管将[]作为第二个参数传递给了更熟悉的componentDidMount和componentWillUnmount心智模型,但通常会有更好的解决方案来避免过于频繁地重新运行效果。另外,别忘了React在浏览器绘制完成后才推迟运行useEffect,所以做额外的工作就没什么问题了。
我们建议在我们的eslint-plugin-react-hooks程序包中使用详尽的下降规则。它会在错误指定依赖项时发出警告,并提出修复建议。
祝您项目顺利,编码愉快!
答案 1 :(得分:0)
简而言之,这是由于使用了错误的useEffect
调用及其依赖项引起的。由于表单中逻辑的每个部分都需要分别处理,因此您需要多种效果,如下所示:
首先,如果要在用户状态更改(从注销到登录)时获取配置文件,则需要一种在用户登录时运行getCurrentProfile
的效果。
useEffect(() => {
// User has been logged in
if (loggedIn) getCurrentProfile();
}, [loggedIn]);
然后,您需要另一个效果来监听profile
的更改(成功获取用户个人资料后,从上方开始),以按预期的方式填充表单字段:
useEffect(() => {
setFormData({
... // see as above
});
}, [profile]);
最后,要基于已完成的字段进入setShow
模态,我建议使用另一个useEffect
来检查这些user
数据(如我所预测的那样,可能是您的表单数据):>
useEffect(() => {
let completeFieldsCounter = 0;
if (user) {
... // see snippets above
}
if(completeFieldsCounter == 9 ){
setShow(false)
} else {
setShow(true)
}
}, [user]);