如何使用Redux正确实现mapStateToProps?

时间:2016-12-10 08:48:28

标签: reactjs redux

我正在尝试做一些非常简单的事情:每次单击按钮时,此组件中的“当前”值都会增加:https://github.com/conorhastings/react-thermometer

问题是,当我构建时,控制台会抛出以下错误:模块构建失败:SyntaxError:意外的令牌,预期((29:11)

在这一行:

function mapStateToProps(state){

这是我的容器的整个代码:

import React, {Component} from 'react';
import Thermometer from "react-thermometer";
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {incrementValue} from '../actions/index';

class Thermo extends Component{
  getValue(){
    return this.props.val;
  }

  render(){
    return(
          <div>
              <Thermometer
                      min={0}
                      max={90}
                      width={10}
                      height={90}
                      backgroundColor={'gray'}
                      fillColor={'pink'}
                      current={this.getValue()}
              />
              <Button onClick={() => this.props.incrementValue(val)}>+</Button>
          </div>
    )
  }

  function mapStateToProps(state){
    return{
      val: state.val
    };
  }

  function matchDispatchToProps(dispatch){
    return bindActionCreators({incrementValue: incrementValue}, dispatch);
  }
}

export default connect(mapStateToProps, matchDispatchToProps)(Thermo);

以防万一,这是我的webpack配置:

var path = require('path');
var webpack = require('webpack');

module.exports = {
    devServer: {
        inline: true,
        contentBase: './src',
        port: 3000
    },
    devtool: 'cheap-module-eval-source-map',
    entry: './dev/js/index.js',
    module: {
        loaders: [
            {
                test: /\.js$/,
                loaders: ['babel'],
                exclude: /node_modules/
            },
            {
                test: /\.scss/,
                loader: 'style-loader!css-loader!sass-loader'
            }
        ]
    },
    output: {
        path: 'src',
        filename: 'js/bundle.min.js'
    },
    plugins: [
        new webpack.optimize.OccurrenceOrderPlugin()
    ]
};

2 个答案:

答案 0 :(得分:5)

将函数放在类之外:

import React, {Component} from 'react';
import Thermometer from "react-thermometer";
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {incrementValue} from '../actions/index';

class Thermo extends Component{
  getValue(){
    return this.props.val;
  }

  render(){
    return(
          <div>
              <Thermometer
                      min={0}
                      max={90}
                      width={10}
                      height={90}
                      backgroundColor={'gray'}
                      fillColor={'pink'}
                      current={this.getValue()}
              />
              <Button onClick={() => this.props.incrementValue(val)}>+</Button>
          </div>
    )
  }


}

function mapStateToProps(state){
    return{
      val: state.val
    };
  }

  function mapDispatchToProps(dispatch){
    return bindActionCreators({incrementValue: incrementValue}, dispatch);
  }

export default connect(mapStateToProps, matchDispatchToProps)(Thermo);

您正在将组件的定义传递给connect返回的函数,因此您无法随时创建该类的实例。 mapStateToPropsmapDispatchToProps完全独立于您的类,并且在Thermo的任何实例生成之前使用。因此你需要把它们放在外面。

答案 1 :(得分:2)

将函数定义移到Component类

之外
class Thermo extends Component {
    // ... component things
}

function mapStateToProps(state){
    return{
      val: state.val
    };
}

function matchDispatchToProps(dispatch){
    return bindActionCreators({incrementValue: incrementValue}, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(Thermo);

由于您使用的是ES6,我们有更好的写作方式connect

class Thermo extends Component {
    // ... component things
}

export default connect(
    (state) => ({ val: state.val }),
    { incrementValue }
)(Thermo);

即您实际上不需要mapStateToPropsmatchDispatchToProps