0
votes

First of all, I temporarily solved the problem that 'this' keeps becoming undefined through disabling 'babel-preset-es2015' and removing 'es2015' styled codes such as 'import', '() => {}', etc. I'm just wondering the fundamental reason why this problem is happening, so I put the question in here.

My project is using React.js, Webpack, Babel, and Electron to make a desktop application. I built UI using React.js, bundled my jsx file using Babel and Webpack.

This is my jsx file:

const React = require('react')
const ReactDOM = require('react-dom')

let Evet = React.createClass({
  handleClick: function () {
    this.props.onUserSelect(this.props.anEvet)
  },
  render: function () {
    return (
      <div className='well well-sm' onClick={this.handleClick}>
        {this.props.anEvet.type}: {this.props.anEvet.kind}
      </div>
    )
  }
})

let EvetInfo = React.createClass({
  render: function () {
    let apisList = []
    this.props.anEvet.apis.forEach((api) => {
      apisList.push(<li>{api}</li>)
    })
    return (
      <div className='well well-lg'>
        <h2>{this.props.anEvet.type} ({this.props.anEvet.kind})</h2>
        <ul>{apisList}</ul>
      </div>
    )
  }
})

let EvetList = React.createClass({
  getInitialState: function () {
    return {
      selectedEvet: {}
    }
  },
  handleSelectEvet: function (anEvet) {
    this.setState({ selectedEvet: anEvet })
  },
  render: function () {
    let list = []
    this.props.evetsList.forEach((evet, idx) => {
      list.push(<Evet key={evet._id} anEvet={evet} onUserSelect={this.handleSelectEvet} />)
    })
    let info
    if (this.state.selectedEvet.kind) info = <EvetInfo anEvet={this.state.selectedEvet} />
    return (
      <div>
        <div className='col-md-4'>{list}</div>
        <div className='col-md-8'>{info}</div>
      </div>
    )
  }
})

ReactDOM.render(
  <EvetList evetsList={evets} />,
  document.getElementById('evetlist')
)

This is my webpack.config.js file.

const path = require('path')

module.exports = {
  entry: [
    './app/components/app.js'
  ],
  output: {
    path: path.join(__dirname, 'app/js/dist'),
    filename: 'bundle.js'
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      loader: 'babel-loader',
      exclude: /node_modules/,
      query: {
        presets: ['es2015', 'react']
      }
    }]
  }
}

When I run my program, I got an error like the below screenshot. enter image description here

When I remove 'es2015 styled code' and disabling 'babel-preset-es2015' in the 'webpack.config.js' file, it works intendedly. Could you let me know why this error is happening when I use 'es2015' preset to bundle it? I want to use 'es2015' style to make my program. '() => ' notation is so cool and convenient. :)

1
Do component Evet and EvetInfo have the same problem? Anthor word, could you post the bulided code of Evet and EvetInfo? - youngwind
@梁少峰 Yes. Both have same problem. At this time, I don't have the builded code. - byron1st

1 Answers

4
votes

You can't use fat-arrow functions just because they are "cool and convenient"-- they have different semantics than normal functions. Specifically, they share a lexical this with their containing scope, instead of creating a new this-- and in a React component which will be in a module, the outer this will be undefined.