Redux - 减少器/动作创建器未正确链接到组件

时间:2017-09-29 16:05:26

标签: javascript reactjs redux

我正在学习如何使用Redux,并且在设置动作和缩减器时遇到了问题。这是我的设置:

行动在这里:

export const loginUser = (test) => {
        return {
            type:'loginUser',
            loggedIn:true
        }
}

export const toggleRegLog = (test) => {
        return {
            type:'toggleRegLog',
        }
}

减速器在这里:

let initialState = [];

const userAuthReducer = (state = initialState,action) => {
  switch (action.type) {
    case 'loginUser':  
      let newState = [...state];
            if(action.loggedIn) {
        newState = "logged-in";
            } else {
                newState = "not-logged-in";
            }
      return newState;
            break;
        case:'toggleRegLog':
            let newState = [...state];
            return action.state;
            break;
    default:
      return state;
  } 
}

export default userAuthReducer;

reducers的组合在一个名为index的文件中:

import {combineReducers} from 'redux';
import userAuthReducer from './reducers/userAuthReducer';

function lastAction(state = null, action) {
  return action;
}

export default combineReducers({
  userAuthReducer
});

演示组件:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import { bindActionCreators } from 'redux';
import * as authActions from './actions/userAuthActions';

class App extends Component {
  constructor(props) {
    super(props);
  }


componentDidMount() {

    console.log(this.props)
}    

  render() {
    return (
      <div>
                <button onClick={this.props.loginUser()}></button>
      </div>
    );
  }

const mapStateToProps = (state) => {
  return {
        userAuthReducer:state.userAuthReducer
  };
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators(authActions,dispatch);
};

export default connect(mapStateToProps,mapDispatchToProps)(App);    
}

我之前以一种更基本的方式让国家工作但是在看了一些更多的教程并决定引入单独的动作创建者(即不仅仅是从我的组件直接调度到减速器)并在我的减速器中引入多个案例它似乎不再起作用了。我的组件上的console.log(this.props)将操作作为函数返回,并将状态返回为undefined。

有人能找到我出错的地方吗?

2 个答案:

答案 0 :(得分:4)

您在此项目设置中遇到了很多错误。

如果您正在运行发布的代码

,您应该会看到它们

让我们来看看你的代码

常数 (错过)

常量对于增加动作和缩减器的一致性非常重要。

export const LOGIN_USER = 'loginUser';

export const TOGGLE_REG_LOG = 'toggleRegLog';

<强> 操作

您的行为没有任何问题,只是一些建议

  • 关注Flux standard action
  • 如果您不使用参数,请不要声明参数
  • 操作不返回新状态,而是描述改变redux存储的行为

import { LOGIN_USER, TOGGLE_REG_LOG } from '../constants/userAuthConstants';

export const loginUser = (loggedIn = true) => {
  return {
    type: LOGIN_USER,
    payload: {
      loggedIn
    }
  }
}

export const toggleRegLog = () => {
  return {
    type: TOGGLE_REG_LOG,
  }
}

<强> 减速

case: toggleRegLog:声明中有错误。 建议:

  • 如果要声明变量,请将您的开关案例包裹在块(花括号)中,这样您就不会使用不同的名称
  • 使用Object.assign代替传播运营商
  • 使用操作数据更改newState
  • 使用常量
  • 使用对象而不是数组作为初始状态

import { LOGIN_USER, TOGGLE_REG_LOG } from '../constants/userAuthConstants';

const initialState ={
  userLoginStatus: 'not-logged-in'
};

const userAuthReducer = (state = initialState, action) => {
  switch (action.type) {
    case LOGIN_USER: {
      const userLoginStatus = action.payload.loggedIn ? 'logged-in' : 'not-logged-in';

      const newState = Object.assign(state, {
        userLoginStatus
      });

      return newState;
    }
    case TOGGLE_REG_LOG: {
      let newState = Object.assign({}, state, {}); // do what you need here

      return newState;
    }
    default:
      return state;
  }
}

export default userAuthReducer;

<强> 组件

当您在按钮中附加onClick事件时,正在执行loginUser函数时,它正在期待函数回调,而是在不执行它的情况下传递loginUser,因此当用户单击时按钮动作将被分派

建议:

  • 如果您不在其中执行任何操作,请避免使用constructor
  • 从redux商店中选择所需的特定属性

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { loginUser } from './actions/userAuthActions';

class App extends Component {
  componentDidMount() {
    console.log(this.props);
  }

  render() {
    const { userLoginStatus, loginUser } = this.props;

    return (
      <div>
        <p> User status: {userLoginStatus}</p>
        <button onClick={loginUser}>click me</button>
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    userLoginStatus: state.userAuthReducer.userLoginStatus
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    loginUser: () => dispatch(loginUser())
  };
};

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

在开始测试任何库/框架之前,请确保您遵循最佳实践,并且您的代码不包含任何错误,否则您可能会开始使用代码做恶梦。

答案 1 :(得分:0)

操作:这里我已经将newState有效负载添加到了在reducer中使用的操作。

export const loginUser = () => {
    return {
        type:'loginUser',
        loggedIn:true


    }
}
export const toggleRegLog = () => {
        return {
            type:'toggleRegLog',
            newState: xyz, //whatever you want it to be
        }
}

减速: 在这里,我将您的初始状态更改为json对象,该对象具有loginStatus的字段。您可以使用同一个对象通过添加其他字段来跟踪其他内容。我已将字段的初始状态设置为&#34; not-logged-in&#34;。在reducer中,使用spread运算符将initail状态扩展到一个新对象中,并覆盖要更新的字段。

let initialState = {
loginStatus:"not-logged-in",
 //other stuff
};


const userAuthReducer = (state = initialState,action) => {
  switch (action.type) {
    case 'loginUser':  
      let newState = {};
            if(action.loggedIn) {
        newState = {...state,  loginStatus:"logged-in"};
            } else {
                newState = {...state,  loginStatus:"not-logged-in"};
            }
      return newState;
            break;
        case:'toggleRegLog':

            return {...state,  loginStatus:action.newState};
            break;
    default:
      return state;
  } 
}

export default userAuthReducer;

App组件:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import { bindActionCreators } from 'redux';
import * as authActions from './actions';

class App extends Component {
  constructor(props) {
    super(props);
  }


componentDidMount() {

    console.log(this.props)
}    

  render() {
    return (
      <div>
                <button onClick={this.props.loginUser}></button>
      </div>
    );
  }
}
const mapStateToProps = (state) => {
  return {
        userAuthReducer:state.userAuthReducer
  };
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators(authActions,dispatch);
};




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