我需要帮助解决这个问题,我正在创建一个Account组件,并在登录后将令牌存储在本地存储中。当我第一次导航到Account页面时,我能够从redux存储访问状态。如果刷新页面,则值为null,但令牌仍在本地存储中。在加载页面时,如何使用令牌进行获取调用?我已经在useEffect((方法内部进行了方法调用。为什么它将用户和配置文件字段的所有值都设置为null?有人能帮我解决这个问题吗?非常感谢。
// Account.js
import React, { Fragment, useEffect } from 'react';
import profilePic from '../../../img/profile.jpeg';
import {
AccountContainer,
IconStyle,
H1Container,
SectionContainer,
ProfileContainer,
FormContainer,
InputContainer,
InputText,
DivContainer,
LabelContainer,
EditButton,
PasswordButton,
ImageContainer,
ImageStyle,
ButtonStyle
} from './Account.style';
import { Redirect } from 'react-router-dom';
import Spinner from '../../spinner/Spinner';
import store from '../../../redux/store';
import { connect } from 'react-redux';
import { loadUser } from '../../../redux/actions/authAction';
import { getUserProfile } from '../../../redux/actions/profileAction';
const Account = ({ loadUser, auth: { user }, getUserProfile, profile: { profile, loading } }) => {
useEffect(() => {
// load user
loadUser();
// get current profile
getUserProfile();
}, [loadUser, getUserProfile]);
return (
profile && loading === null
?
<Spinner />
:
<Fragment>
<AccountContainer>
<H1Container className="text-center">
<p>
<IconStyle className="fa fa-user-circle" />
</p>
<h1>My Account</h1>
<p>Update your email or change your password here</p>
</H1Container>
</AccountContainer>
<SectionContainer>
<ProfileContainer>
<ImageContainer>
<p>
<ImageStyle src={profilePic} alt="Profile picture" />
</p>
<ButtonStyle type="button">Change Photo</ButtonStyle>
</ImageContainer>
</ProfileContainer>
<FormContainer>
<form>
<DivContainer>
<LabelContainer htmlFor="submit"></LabelContainer>
<EditButton type="button">Edit Profile</EditButton>
<PasswordButton type="button">Change Password</PasswordButton>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="username">Username</LabelContainer>
<InputContainer>
<InputText type="text" className="form-control" readOnly value={user.username} />
</InputContainer>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="fullname">Full Name</LabelContainer>
<InputContainer>
<InputText type="text" className="form-control" readOnly value={user.fullname} />
</InputContainer>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="email">Email</LabelContainer>
<InputContainer>
<InputText type="email" className="form-control" readOnly value='email' />
</InputContainer>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="country">Country</LabelContainer>
<InputContainer>
<InputText type="text" className="form-control" readOnly value='country' />
</InputContainer>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="blogs">Number of blog posts</LabelContainer>
<InputContainer>
<InputText type="text" className="form-control" readOnly value="20" />
</InputContainer>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="facebook">Facebook</LabelContainer>
<InputContainer>
<InputText type="text" className="form-control" readOnly value="www.facebook.com" />
</InputContainer>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="twitter">Twitter</LabelContainer>
<InputContainer>
<InputText type="text" className="form-control" readOnly value="www.twitter.com" />
</InputContainer>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="linkedin">Linkedin</LabelContainer>
<InputContainer>
<InputText type="text" className="form-control" readOnly value="www.linkedin.com" />
</InputContainer>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="instagram">Instagram</LabelContainer>
<InputContainer>
<InputText type="text" className="form-control" readOnly value="www.instagram.com" />
</InputContainer>
</DivContainer>
<DivContainer>
<LabelContainer htmlFor="join">Join Date</LabelContainer>
<InputContainer>
<InputText type="text" className="form-control" readOnly value="09-10-2020 3:00PM" />
</InputContainer>
</DivContainer>
</form>
</FormContainer>
</SectionContainer>
</Fragment>
)
}
const mapStateToProps = state => ({
auth: state.auth,
profile: state.profile
});
export default connect(mapStateToProps, { loadUser, getUserProfile })(Account);
@SethLutske是的,我想是的。请看动作和减速器,如果这有帮助,请告诉我。
// LOAD USER WITH AUTH TOKEN
export const loadUser = () => async dispatch => {
// check if token exists
if (localStorage.token) {
// call function to set it to the global header
setAuthToken(localStorage.token);
}
try {
const res = await axios.get('/api/auth');
dispatch({
type: USER_LOADED,
payload: res.data
})
} catch (error) {
dispatch({
type: AUTH_FAIL
})
}
}
// define initial states
const initialState = {
// get token from local storage
token: localStorage.getItem('token'),
isAuthenticated: null,
loading: true,
user: null
};
const authReducer = (state = initialState, action) => {
switch (action.type) {
case USER_LOADED:
return{
...state,
isAuthenticated: true,
loading: false,
user: action.payload
}
case REGISTER_SUCCESS:
case LOGIN_SUCCESS:
// set token
localStorage.setItem('token', action.payload.token);
return{
...state,
...action.payload,
isAuthenticated: true,
loading: false
}
case REGISTER_FAIL:
case LOGIN_FAIL:
case AUTH_FAIL:
case CLEAR_PROFILE:
case LOGOUT:
// remove token
localStorage.removeItem('token');
return{
...state,
token: null,
isAuthenticated: false,
loading: false,
user: null
}
default:
return state;
}
}
export default authReducer;
您可以在Account组件的componentDidMount中设置令牌形式localStorage的State。
componentDidMount(){
this.setState({
token:localStorage.getItem('token')
})
}