如何在redux存储库中重新加载页面时访问本地存储库?

时间:2020-11-12 15:34:26

标签: reactjs redux react-redux local-storage

我需要帮助解决此问题,我将在登录后创建一个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);

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

您可以在Account组件的componentDidMount中以StateStorage形式设置令牌。

componentDidMount(){
    this.setState({
        token:localStorage.getItem('token')
    })
}