使用mapDispatchToProps时,在事件侦听器上对redux props进行undefined反应

时间:2017-08-31 14:09:36

标签: reactjs redux

我第一次使用react / redux并试图将简单的操作addClick绑定到'点击'事件,但是当我点击时收到错误:

Uncaught TypeError: Cannot read property 'props' of undefined

我的(精简版)代码是:

import {addClick} from './actions'
const mapDispatchToProps = {addClick}
class App extends Component {
    componentDidMount() {
        document.addEventListener('click', this.props.addClick)
    }
    componentWillUnmount() {
        document.removeEventListener('click', this.props.addClick)
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(App)

在没有使用mapDispatchToProps使用在类中定义并绑定到构造函数中的this的动作创建器的情况下实现它之前。但我认为mapDispatchToProps的一部分要点是将动作创建者绑定到this(以及将其包裹在dispatch中)

我错过了什么?

谢谢!

2 个答案:

答案 0 :(得分:2)

从文档中我可以看出,用于const mapDispatchToProps = {addClick}的对象简写(mapDispatchToProps)不会将this绑定到任何内容。它只是看到您的addClick动作创建者通过调度被调用。因此,如果您在组件中执行addClick(3),那么这将导致调用看起来像dispatch(addClick(3))

我不确定为什么您的动作创建者需要访问this。难道你不能把它作为参数需要的数据传递给它吗?这样组件中的调用可能看起来像

componentDidMount() {
        const {addClick, someOtherProp} = this.props;
        document.addEventListener('click', () => addClick(someOtherProp));
    }

答案 1 :(得分:1)

你在addClick行动中使用道具吗?

检查此示例:

import React from "react";
import { render } from "react-dom";
import { connect, Provider } from "react-redux";
import { createStore } from "redux";

function addClick(event) {
  return {
    type: "CLICK",
    payload: `pageX: ${event.pageX} | pageY: ${event.pageY}`
  };
}

const mapStateToProps = state => {
  return {
    clickXY: state
  };
};
const mapDispatchToProps = { addClick };

class App extends React.Component {
  componentDidMount() {
    document.addEventListener("click", this.props.addClick);
  }
  componentWillUnmount() {
    document.removeEventListener("click", this.props.addClick);
  }
  render() {
    return (
      <h1>
        Click message: {this.props.clickXY}
      </h1>
    );
  }
}

function clickReducer(state = "None", action) {
  switch (action.type) {
    case "CLICK": {
      return action.payload;
    }
    default:
      return state;
  }
}

let store = createStore(clickReducer);

const AppContainer = connect(mapStateToProps, mapDispatchToProps)(App);

class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <AppContainer />
      </Provider>
    );
  }
}

render(<Root />, document.getElementById("root"));

链接到editor

所以bind在这段代码中效果很好。