состояние redux перейдет в исходное состояние после перезагрузки страницы NEXT. JS - PullRequest
1 голос
/ 13 июля 2020

У меня есть интернет-магазин с регистрацией и логином. После регистрации токен сохраняется в cook ie, а состояние аутентификации обновляется. Это работает. Но проблема в том, что когда я обновляю sh страницу, состояние аутентификации устанавливается равным нулю. Пожалуйста, проверьте мой магазин и редукторы.

store.js

import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'

import rootReducer from './reducers';

const initialState = {};
const middleware = [thunk];

const store = createStore(rootReducer, initialState, 
composeWithDevTools(applyMiddleware(...middleware)));

export default store;

authReducer.js

import * as types from '../types'

export const authReducer = (state = { token: null }, action) => {
    switch (action.type) {
        case types.AUTHENTICATE:
            return {
                ...state,
                token: action.payload
            };
        case types.DEAUTHENTICATE:
            return {
                token: null
            };
        default:
            return state;
    }
};

authAction.js

import * as types from '../types'
import axios from 'axios'
import cookie from 'js-cookie';
import * as api from '../../pages/api'
import Router from 'next/router';

export const authenticate = user => async dispatch => {
    const res = await axios.post(api.URL_REGISTER, {user})
        .then(res => {
            if (res.data.response === 200) {
                setCookie('token', res.data.data.token);
                Router.push('/');

                dispatch({
                    type: types.AUTHENTICATE,
                    payload: res.data.data.token
                })
            }
            else
                dispatch({
                    type: types.AUTHENTICATE,
                    payload: res.data
                })
        }).catch(error => {
            console.log(error);
        });
}

// gets the token from the cookie and saves it in the store
export const reauthenticate = token => {
    return dispatch => {
        dispatch({ type: types.AUTHENTICATE, payload: token });
    };
};

// removing the token
export const deauthenticate = () => {
    return dispatch => {
        removeCookie('token');
        Router.push('/');
        dispatch({ type: types.DEAUTHENTICATE });
    };
};

/**
 * cookie helper methods
 */

export const setCookie = (key, value) => {
    if (process.browser) {
        cookie.set(key, value, {
            expires: 1,
            path: '/'
        });
    }
};

export const removeCookie = key => {
    if (process.browser) {
        cookie.remove(key, {
            expires: 1
        });
    }
};

export const getCookie = key => {
    return cookie.get(key);
};

Header.js

import React from 'react'
import Link from 'next/link'
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'
import { faSearch, faShoppingCart, faUserCircle, faBoxOpen, faHeart } from '@fortawesome/fontawesome-free-solid'
import { deauthenticate } from '../../store/actions/authAction';
import { connect } from 'react-redux';

const Header = ({ deauthenticate, isAuthenticated }) => (
    <div>
        
                    <div className="col-12 col-md-4 col-lg-3">
                        <div className="text-center text-md-right">
                            <div className="d-inline loginDrop">
                                <Link href="/">
                                    <a className="signinBtn mr-5">{!isAuthenticated ? "Sign In" : "My Account"}</a>
                                </Link>
                                <div className={!isAuthenticated ? "login-content" : "login-content logout-content"}>
                                    <p>&nbsp;</p>
                                    <div className="login-inner">
                                        <Link href={!isAuthenticated ? "/login" : "/profile"}><a><FontAwesomeIcon icon={faUserCircle} className="mr-2"/> Your Profile</a></Link>
                                        <Link href={!isAuthenticated ? "/login" : "/orders"}><a><FontAwesomeIcon icon={faBoxOpen} className="mr-2 orderIcon"/> Orders</a></Link>
                                        <Link href={!isAuthenticated ? "/login" : "/wishlist"}><a><FontAwesomeIcon icon={faHeart} className="mr-2"/> Whishlist</a></Link>
                                        <div className="otherDrop">
                                            {!isAuthenticated ?
                                                <>
                                                <p className="first">Don't have an account?</p>
                                                <p className="register"><Link href="/register" as="/register"><a>Register</a></Link></p>
                                                <p className="login"><Link href="/login"><a>Login</a></Link></p>
                                                </>
                                            :
                                                <p className="login"><a href="#" onClick={deauthenticate}>Logout</a></p>
                                            }
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <Link href="/">
                                <a className="cartBtn"><FontAwesomeIcon icon={faShoppingCart} className="mr-xl-1"/> Cart</a>
                            </Link>
                        </div>
                    </div>
    </div>
)

const mapStateToProps = state => ({ isAuthenticated: !!state.authentication.token });

export default connect(
mapStateToProps,
{ deauthenticate }
)(Header);

_app.js

import App from 'next/app'
import React from 'react'
import {Provider} from 'react-redux'
import {createWrapper} from 'next-redux-wrapper'
import store from '../store/store'

class MyApp extends App {
    render() {
        const {Component, pageProps} = this.props

        return (
            <Provider store={store}>
                <Component {...pageProps}></Component>
            </Provider>
        )
    }
}

const makestore = () => store;
const wrapper = createWrapper(makestore);

export default wrapper.withRedux(MyApp);

Как исправить начальное состояние, чтобы оно не было нулевым даже после refre sh страницы. Я действительно застрял здесь. Есть ли вариант исправить.

1 Ответ

1 голос
/ 13 июля 2020

Все, что вам нужно, - это сохранить свое состояние redux в браузере refre sh с помощью промежуточного программного обеспечения redux, например redux-persist , ie:

if (isClient) {
  store = createStore(
    persistReducer(persistConfig, rootReducer),
    initialState,
    composeWithDevTools(applyMiddleware(...middleware))
  );
}
...