Redux MapDispatchToProps无法运作

时间:2019-10-14 12:55:40

标签: reactjs redux react-redux

因此,我是Redux的新手,我正在尝试使该基本模型正常工作,以便可以快速处理一个小型个人项目,我进行了所有设置,没有任何错误,但是我正在尝试测试和实现我的功能没有用,所以我希望有人可以指出我错过的事情。

我遵循了多个不同的教程,每个教程都有不同的方法,所以我有些失落,为此我深表歉意。

我的store.js看起来像这样

import rootReducer from "./reducers";
import thunk from "redux-thunk";
const store = createStore(rootReducer, applyMiddleware(thunk));
export default store;

我在reducers文件夹的index.js中使用了CombineReducers,而auth:指向authReducer.js文件,这就是


const INIT_STATE = {
  email: "",
  password: "",
  isLoggedIn: "false"
};

export default (state = INIT_STATE, action) => {
  switch (action.type) {
    case IS_LOGGED_IN_CHANGE:
      console.log(action);
      return {
        isLoggedIn: action.value
      };
    default:
      return state;
  }
};

现在我的目标是要有一个将“ IsLoggedIn”初始状态更改为真实字符串而不是false的按钮,我进入了action文件夹,并制作了一个authActions.js,看起来像这样

import { IS_LOGGED_IN_CHANGE } from "../actions/types";
import store from "../store";

export const isLoggedInChange = value => {
  return dispatch => {
    dispatch({
      type: IS_LOGGED_IN_CHANGE,
      value
    });
  };
};

最后,我想向您展示我的组件页面,其中显示了所有这些内容,就像这样

import { connect } from "react-redux";

import styles from "./Landing.module.css";
import { isLoggedInChange } from "../../actions/authActions";

class Landing extends Component {
  makeTrue = () => {
    isLoggedInChange("true");
  };

  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: ""
    };
  }
  render() {
    return (
      <div className={styles.background}>
        <button onClick={this.makeTrue}>MAKE TRUE</button>
        {this.props.isLoggedIn}
      </div>
    );
  }
}

const mapStateToProps = state => ({
  isLoggedIn: state.auth.isLoggedIn
});

const mapDispatchToProps = dispatch => ({
  isLoggedInChange: value => dispatch(isLoggedInChange(value))
});

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

你能告诉我是否丢了东西吗?为什么按钮不更改存储状态? TIA

3 个答案:

答案 0 :(得分:1)

这里有两个问题。您是直接致电您的行动创建者,而不是props.isLoggedInChange

  makeTrue = () => {
    this.props.isLoggedInChange("true");
  };

您需要在行动中传播旧状态

case IS_LOGGED_IN_CHANGE:
  console.log(action);
  return {
    ...state,
    isLoggedIn: action.value
  };
  

mapDispatchToProps的意义不是像我一样可以立即使用该功能

是的,问题是mapDispatchToProps将包装在dispatch中的一个(或多个)函数注入到props中。

import { actionCreator } from './actions

const mapDispatchToProps = dispatch =>({
    actionCreator : () => dispatch(actionCreator)
})  

现在您有两个actionCreator,一个在作用域中全局可用(这是您的动作创建者),而props.actionCreator是包装在dispatch中的原始动作创建者。因此,当您从组件内部调用actionCreator()时,不会抛出任何错误(因为在作用域中有一个名为actionCreator的函数,但是您将调用错误的函数,所以找到了正确的函数)在props.actionCreator

  

我为什么需要传播状态?

reducer是一个纯函数,它接收stateaction并返回新状态。当您刚返回

return {
    isLoggedIn : true
}

您实际上是在覆盖原始状态(其中包含其他属性),因此首先您需要spread保持原始状态以保持其结构完整性,然后覆盖您想要的属性

return{
   ...state,
   isLoggedIn : !state.isLoggedIn
}

答案 1 :(得分:1)

Redux状态是不可变的,因此您需要返回状态的全新实例,并将reducer状态更改为以下状态。

export default (state = INIT_STATE, action) => {
   switch (action.type) {
    case IS_LOGGED_IN_CHANGE:
       console.log(action);
       return Object.assign({}, state, {
         isLoggedIn: action.value
       });
    default:
      return state;
  }
};

关键区别在于

return Object.assign({}, state, {
         isLoggedIn: action.value
       });

Object.assign以我在这里使用的方式将状态对象组合成一个全新的对象。检查redux reducers中的不变性,我建议添加redux-immutable-state-invariant作为开发包,它可以检测何时直接修改状态并帮助指出此类错误

答案 2 :(得分:0)

使用isLoggedIn的新值返回状态。像这样使用减速器:

case IS_LOGGED_IN_CHANGE:
  console.log(action);
  return {
    ...state,
    isLoggedIn: action.value
  };