8 Replies - 129 Views - Last Post: 10 July 2019 - 10:18 AM

#1 Neonz27   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 38
  • Joined: 08-May 16

Component's props are undefined. (React/Redux)

Posted 08 July 2019 - 08:15 PM

So after about 2 days solid of consistent headaches, I thought I had finally figured out Redux when! GASP! My `mapDispatchToProps` function worked flawlessly, yet the `mapStateToProps` function seems to have made the component's props return undefined. Any help would be massively appreciated as this is still on my mind and I'm not even working on it right now. It's really frustrating me and I would like to fix it as soon as possible.

Posted Image

Actions File
// Exporting All Redux Action Types For The Navbar Component
export const CHANGE_IS_LOGGED_IN = "CHANGE_IS_LOGGED_IN";
export const CHANGE_USERNAME = "CHANGE_USERNAME";
export const CHANGE_ACTIVE_PAGE = "CHANGE_ACTIVE_PAGE";

// Exporting All Redux Action Creators For The Navbar Component
// -----------------------------------------------------------------------------

// `changeIsLoggedIn` Redux Action Creator
// Changes what the UI shows the user based on the variable `isLoggedIn`.
export const changeIsLoggedIn = (isLoggedIn) => {
  return {
    type: CHANGE_IS_LOGGED_IN,
    isLoggedIn
  };
};

// `changeUsername` Redux Action Creator
// Changes the username to display on the UI based on the variable `username`.
export const changeUsername = (username) => {
  return {
    type: CHANGE_USERNAME,
    username
  };
};

// `changeActivePage` Redux Action Creator
// Changes which page is highlighted as active on the Navbar component based on the variable `active`.
export const changeActivePage = (active) => {
  return {
    type: CHANGE_ACTIVE_PAGE,
    active
  };
};


Reducer File
// Importing Redux Action Types For The Navbar Component
import {
  CHANGE_IS_LOGGED_IN,
  CHANGE_USERNAME,
  CHANGE_ACTIVE_PAGE
} from "../actions";

// Setting The Initial State Of The Reducer
const initialState = {
  isLoggedIn: "false",
  username: "user",
  active: "home"
};

// Redux Reducer For The Navbar Component
const navbarReducer = (state = initialState, action) => {
  // Using a switch statement to sift for specific action types.
  switch(action.type) {
    // When any modifying Redux action is found, return a new copy of the state.
    // This keeps Redux's store immutable.
    case CHANGE_IS_LOGGED_IN:
      return Object.assign({}, state, {
        isLoggedIn: action.isLoggedIn,
        username: state.username,
        active: state.active
      });
    case CHANGE_USERNAME:
      return Object.assign({}, state, {
        isLoggedIn: state.isLoggedIn,
        username: action.username,
        active: state.active
      });
    case CHANGE_ACTIVE_PAGE:
      return Object.assign({}, state, {
        isLoggedIn: state.isLoggedIn,
        username: state.username,
        active: action.active
      });
    default:
      return state;
  }
};

// Exporting The Redux Reducer For The Navbar Component
export default navbarReducer;


React Component
// React Dependencies
import React from "react";
import { Link } from "react-router-dom";

// Redux Dependency
import { connect } from "react-redux";

// Proprietary Dependency
import {
  CHANGE_IS_LOGGED_IN,
  CHANGE_USERNAME,
  CHANGE_ACTIVE_PAGE,
  changeIsLoggedIn,
  changeUsername,
  changeActivePage
} from "./actions/navbarActions";

// Mapping Redux State To This Component's Props
const mapStateToProps = (state) => {
  return {
    isLoggedIn: state.isLoggedIn,
    username: state.username,
    active: state.active
  };
};

// Mapping Redux Action Creators To This Component's Props
const mapDispatchToProps = {
  changeIsLoggedIn,
  changeUsername,
  changeActivePage
};

// Navigation Component is a state-less & functional React Component.
const Navbar = (props) => {
  console.log(props);

  return (
    <div id="navbar-container">
      <nav className="navbar navbar-expand-lg navbar-dark bg-primary">
        <Link to="/" className="navbar-brand">Miner's Codex</Link>

        <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
          <span className="navbar-toggler-icon" />
        </button>

        <div className="collapse navbar-collapse" id="navbarCollapse">
          <ul className="navbar-nav mr-auto">
            { props.active === "home" ? (
              <li className="nav-item active">
                <Link to="/" className="nav-link">Home</Link>
              </li>
            ) : (
              <li className="nav-item">
                <Link to="/" className="nav-link">Home</Link>
              </li>
            ) }

            { props.active === "budget" ? (
              <li className="nav-item active">
                <Link to="/budget" className="nav-link">Budget Graphics Cards</Link>
              </li>
            ) : (
              <li className="nav-item">
                <Link to="/budget" className="nav-link">Budget Graphics Cards</Link>
              </li>
            ) }

            { props.active === "highend" ? (
              <li className="nav-item active">
                <Link to="/premium" className="nav-link">High-End Graphics Cards</Link>
              </li>
            ) : (
              <li className="nav-item">
                <Link to="/premium" className="nav-link">High-End Graphics Cards</Link>
              </li>
            ) }

            { props.active === "asics" ? (
              <li className="nav-item active">
                <Link to="/asics" className="nav-link">ASIC Miners</Link>
              </li>
            ) : (
              <li className="nav-item">
                <Link to="/asics" className="nav-link">ASIC Miners</Link>
              </li>
            ) }
          </ul>

          { props.isLoggedIn === "true" ? (
            <ul className="navbar-nav ml-auto">
              <li className="nav-item">
                <p className="nav-link">Hello there, { props.username }!</p>
              </li>
            </ul>
          ) : (
            <ul className="navbar-nav ml-auto">
              <li className="nav-item">
                <Link to="/" className="nav-link"><i className="fas fa-user-plus"></i> Register</Link>
              </li>
              <li className="nav-item">
                <Link to="/" className="nav-link"><i className="fas fa-user-lock"></i> Login</Link>
              </li>
            </ul>
          ) }
        </div>
      </nav>
    </div>
  );
};

// Exporting React Component
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Navbar);


Is This A Good Question/Topic? 0
  • +

Replies To: Component's props are undefined. (React/Redux)

#2 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7442
  • View blog
  • Posts: 15,438
  • Joined: 16-October 07

Re: Component's props are undefined. (React/Redux)

Posted 09 July 2019 - 05:23 AM

You're actually a victim of a linting rule (no-unused-vars) somewhere in your tool chain. You could reasonably turn that rule off, but it's not a bad rule: I use it. So, instead, how to fix it.

Your actions file is fine. At this level, you need to export those constants for the reducer. However, you don't need those constants in your component. Indeed, that's the very reason you wrote all those action functions. In the component, you only are using the functions.

With a decent editor, the should be highlighted for you. e.g.
Attached Image

Note the graying of the unused vars. So, um, take those out of the import. ;)

I really like Visual Studio Code for this stuff. Regardless of your tools, make sure they syntax highlight at the very least. And code completion, as well as you can get in JS.

Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#3 Neonz27   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 38
  • Joined: 08-May 16

Re: Component's props are undefined. (React/Redux)

Posted 10 July 2019 - 03:32 AM

I fixed that, it was actually a typo. The bad news is the component still isn't getting the state dispatched to its props. When I use the Redux Dev Tools Extension it shows the state change appropriately according to the dispatch functions, but the actual DOM itself is not getting the data it needs from the state.

View Postbaavgai, on 09 July 2019 - 06:23 AM, said:

You're actually a victim of a linting rule (no-unused-vars) somewhere in your tool chain. You could reasonably turn that rule off, but it's not a bad rule: I use it. So, instead, how to fix it.

Your actions file is fine. At this level, you need to export those constants for the reducer. However, you don't need those constants in your component. Indeed, that's the very reason you wrote all those action functions. In the component, you only are using the functions.

With a decent editor, the should be highlighted for you. e.g.
Attachment foo.PNG

Note the graying of the unused vars. So, um, take those out of the import. ;)/>/>

I really like Visual Studio Code for this stuff. Regardless of your tools, make sure they syntax highlight at the very least. And code completion, as well as you can get in JS.

Hope this helps.

This post has been edited by Neonz27: 10 July 2019 - 03:34 AM

Was This Post Helpful? 0
  • +
  • -

#4 Neonz27   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 38
  • Joined: 08-May 16

Re: Component's props are undefined. (React/Redux)

Posted 10 July 2019 - 04:02 AM

When I log the `state` in the `mapStateToProps`, I get the real Redux state.
When I log the `props` in the `Navbar` Component, I get all undefined props.
Was This Post Helpful? 0
  • +
  • -

#5 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7442
  • View blog
  • Posts: 15,438
  • Joined: 16-October 07

Re: Component's props are undefined. (React/Redux)

Posted 10 July 2019 - 04:21 AM

Well, that's quite a different problem, isn't it?

Step one, make sure you got what you expected to get. Sounds like you've already did this, but just in case:
const mapStateToProps = (state) => {
  console.log("mapStateToProps state", state);
  const result = {
    isLoggedIn: state.isLoggedIn,
    username: state.username,
    active: state.active
  };
  console.log("mapStateToProps result", result);
  return result;
};



Frankly, I never use mapDispatchToProps, so I can't speak to it. However, if I was doping out a problem, I'd remove it initially just to see if things behave better.
Was This Post Helpful? 0
  • +
  • -

#6 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7442
  • View blog
  • Posts: 15,438
  • Joined: 16-October 07

Re: Component's props are undefined. (React/Redux)

Posted 10 July 2019 - 04:29 AM

Ok, as an aside, the above code is annoying me. I'd rather set it up as:
const trace = (name, f) =>
  x => {
    console.log(name, "in", x);
    const result = f(x);
    console.log(name, "out", result);
    return result;
  };

const mapStateToProps = trace("mapStateToProps", (state) => {
  const { isLoggedIn, username, active } = state;
  return { isLoggedIn, username, active };
});


Was This Post Helpful? 0
  • +
  • -

#7 Neonz27   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 38
  • Joined: 08-May 16

Re: Component's props are undefined. (React/Redux)

Posted 10 July 2019 - 09:20 AM

Yeah this is turning out to be quite the headache. I was really just wanting to get more work done on my project, but I can't for the life of me get these props to change properly. I attached a screenshot of the latest logs with this reply. Also as a side note please ignore the fact that some of the variables hold true/false information but are actually strings. Has no relevance to this problem really, but I just wanted to mention it so I don't seem like a complete imbecile.

Posted Image

This post has been edited by Neonz27: 10 July 2019 - 09:22 AM

Was This Post Helpful? 0
  • +
  • -

#8 Neonz27   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 38
  • Joined: 08-May 16

Re: Component's props are undefined. (React/Redux)

Posted 10 July 2019 - 09:42 AM

I take back what I said about not being a complete imbecile. I am most certainly an idiot. I wasn't getting my props dispatched because I was using state.var format and not state.navbar.var format.

View PostNeonz27, on 10 July 2019 - 10:20 AM, said:

Yeah this is turning out to be quite the headache. I was really just wanting to get more work done on my project, but I can't for the life of me get these props to change properly. I attached a screenshot of the latest logs with this reply. Also as a side note please ignore the fact that some of the variables hold true/false information but are actually strings. Has no relevance to this problem really, but I just wanted to mention it so I don't seem like a complete imbecile.

Posted Image

Was This Post Helpful? 0
  • +
  • -

#9 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7442
  • View blog
  • Posts: 15,438
  • Joined: 16-October 07

Re: Component's props are undefined. (React/Redux)

Posted 10 July 2019 - 10:18 AM

Heh, yeah, this won't be the last time you run into that. But now you'll be extra aware of it. Glad you figured it out.

I prefer Typescript to plain old JS for this kind of thing. Having type validation and catching those type of errors at design time, rather than run time, is well worth the effort of setting up a stack to use TypeScript.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1