0
votes

As the title suggests, I'm struggling to get my Redux state to update using the reducer. I'm also using Redux with React. In this context, I'm using the Redux state to hold the boolean value of whether a user is signed in with a JWT token. I'm fairly certain I have my reducers correctly set up because I can console log out the initial authenticated state which is set to false by default. BUT when I run the AUTH_USER action which tells the reducer to update the state to have authenticated = true, nothing happens. When logging the redux state of auth, it remains false even after I've run the action for AUTH_USER. It seems to make it into the switch statement in the reducer correctly because the console.log shows up in the terminal. I am getting my console log from my header component's componentDidMount lifecycle method which renders on every part of my React application.

Index.js of Reducers (/src/reducers/index.js)

import { combineReducers } from 'redux';
import authReducer from './reducer_auth';

const rootReducer = combineReducers({
  auth: authReducer
});

export default rootReducer;

The Authentication Reducer (/src/reducers/reducer_auth.js)

import { AUTH_USER, DEAUTH_USER } from '../actions/types';

export default function (state = { authenticated: false, error: "" }, 
action) {
  switch(action.type) {
    case AUTH_USER:
      console.log('THIS DOES SHOW UP IN CONSOLE')
      return {...state, error: "", authenticated: true };
    case DEAUTH_USER:
      return {...state, error: "", authenticated: false };
    default:
      return state;
  }
}

The Action Creator for signing in (/src/actions/index.js)

import axios from 'axios';
import history from '../utils/historyUtils';

import { AUTH_USER, DEAUTH_USER } from './types';

const ROOT_URL = 'http://localhost:8888';

export function signInUser(username, password) {
  const signInRequest = axios.post(`${ROOT_URL}/wp-json/jwt-auth/v1/token`, {
    "username": username,
    "password": password
  });

  return (dispatch) => {
    return signInRequest.then(response => {
      localStorage.setItem('token', JSON.stringify(response.data.token));

      dispatch({
        type: AUTH_USER,
        payload: { authenticated : true }
      })

      history.push('/');
      history.go();
    })
  }
}

Header Component (/src/containers/header.js)

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { signOutUser } from '../actions';

import '../styles/header.css';

class Header extends Component {
  componentDidMount() {
    console.log('authenticated from header: ', this.props.authenticated)
  }

  handleLogout(event) {
    event.preventDefault();
    localStorage.removeItem('token');

  }

  render() {
    return (
      <div className="container">
        <header>
          <div id="branding">
            <h1><Link to="/">INSERT BRAND HERE</Link></h1>
          </div>
          <nav>
            <ul>
              <li><Link to="/">Home</Link></li>
              <li><Link to="/contact">Contact</Link></li>
              <li><Link to="/services">Services</Link></li>
              <li><Link to="/Portfolio">Portfolio</Link></li>
              <li><Link to="/about">About</Link></li>
              <li><Link to="/blog">Blog</Link></li>
              {/* {this.props.authenticated ? <li>Logout</li> : <li><Link to="/signin">Login</Link></li>} */}
              <li><Link to="/signin">Login</Link></li>
            </ul>
          </nav>
        </header>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    authenticated: state.auth
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    signOutUser
  }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(Header);

Index.js that holds Routes (/src/index.js)

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import reduxThunk from 'redux-thunk';

import reducers from './reducers';
import Home from './components/home';
import About from './components/about';
import Blog from './containers/blog';
import Contact from './components/contact';
import Portfolio from './components/portfolio';
import Services from './components/services';
import registerServiceWorker from './registerServiceWorker';
import SignIn from './containers/signIn_form';

const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <BrowserRouter>
      <div>
        <Switch>
          <Route path="/about" component={About} />
          <Route path="/blog" component={Blog} />
          <Route path="/contact" component={Contact} />
          <Route path="/portfolio" component={Portfolio} />
          <Route path="/services" component={Services} />
          <Route path="/signin" component={SignIn} />
          <Route path="/" component={Home} />
        </Switch>
      </div>
    </BrowserRouter>
  </Provider>
, document.getElementById('root'));
registerServiceWorker();

If anyone could help shed some light on this issue, I would be super grateful!

1
you say "nothing happens" but you haven't posted any code where something would happen. where are you logging it expecting the state to change?azium
Gotcha, let me go add thatCalvin
Can you post your index.js as well where you are using <Route>Aaqib
All updated, including relative file locations too!Calvin
There is no auth property in your state. In your mapStateToProps, this authenticated: state.auth should be this authenticated: state.authenticated.Rick Jolly

1 Answers

0
votes

Thanks everyone for the comments, you're all awesome! It helped me realize that the history npm module I was using for programatic navigation in my action creator was resetting my redux state for some reason (if anyone's curious, here's the link for the github of the history module: https://github.com/ReactTraining/history). After removing the module from my application, the redux state now updates and stays updated as expected.