0

Banging my head against a wall here while making the UI for my app using React/Redux. The problem is that when my action is fired-off by the client mutating state it turns the piece of state I'm changing into a nested object.

In this case I am trying to change the piece of my state loginForm to either be "login" or "signUp". When I fire off my action the prop loginForm (passed down into my component from state) looks like this: this.props.loginForm.loginForm = "login".

client-side code:

import React from "react";

    import LoginForm from "../minor/LoginForm";

    const Login = React.createClass({

      displayForm(){

        if (this.props.loginForm === "login"){
          return <span>Login</span>
        } else if (this.props.loginForm === "signUp"){
          return <span>Sign Up</span>
        } else {
          console.log("meh")
        }

      },

      renderLogin(){
        this.props.chooseForm("login");
      },

      renderSignUp(){
        this.props.chooseForm("signUp");
      },

      render(){

        return(

            <div className="loginBox">
              <h1>Slots</h1>
              <button onClick={this.renderLogin}  name="login" >Login</button>
              <button onClick={this.renderSignUp} name="signUp" >Sign Up</button>            
              {this.displayForm()}
            </div>
          )
      }
    });

    export default Login;

userActions.js

export function chooseForm(form){
  console.log("choosing form")

  return {
    type: "CHOOSE_FORM",
    form
   }
}

userReducer.js

export function loginForm(state=null, action){

  switch(action.type){

  case "CHOOSE_FORM":

    return {...state, loginForm: action.form };


  default:
    return state;
  }
}

The aim here is to then display the proper component associated with the value of this.prop.loginForm which is unachievable due to my issue stated above.

Update

mainReducer.js (combinedReducer)

import {combineReducers} from "redux";
import {routerReducer} from "react-router-redux";

// reducers
import { loginStatus, loginForm }from "./userReducer";

const rootReducer = combineReducers({ loginStatus, loginForm, routing:      routerReducer});

 export default rootReducer;
1
  • 1
    There aren't enough details-but check your combined reducers. I assume you're not using react-redux? Commented Feb 8, 2017 at 0:57

2 Answers 2

2

Without seeing the rest of your code, I'm going to make an educated guess and say this looks like it could be a problem within a combinedReducers file. If you are using combineReducers read on...

It could be that within that you are setting the Redux state to something like:

loginForm: userReducer
// so the Redux state would be set have a property in it
// 'loginForm' set to {loginForm:'login'}

The solution:

Modify your combineReducers to:

loginForm: userReducer.loginForm
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the educated guess. I updated my question to include my equivalent of combineRecuders. If I am understanding you correctly I need to use dot notation to get those methods to work without making my state a bunch of nested objects. Will test out, thank you.
1

Because your loginForm reducer is a slice reducer you should just return the value for that slice of state, not the entire state, ie you should return the form value:

case "CHOOSE_FORM": 
    return action.form;

Which would replace the loginForm state key with "login" or "signUp" when handling those actions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.