Lexical scope of 'this' in React.createCla

2019-09-13 01:06发布

This question already has an answer here:

I am relatively new to es6 and react. I was following up a tutorial on creating react components and wondered if es6 arrow functions would work same while defining the component functions. Given the lexical scope of 'this' while using arrow functions, i thought it would work.

But 'this' object seems to be resolving to 'undefined' in babel transpiled code. Any specific explanation on why this does not resolve to the defining component variable ? Although using method shorthand and extending es6 classes works, i am just curious.

Component with arrow functions:

const PromptContainer = React.createClass({
  getInitialState: () => ({
    username: '',
  }),
  onInputChange: (e) => {
    this.setState({
      username: e.target.value,
    });
  },
  render: () => (
    <div className="jumbotron col-sm-6 col-sm-offset-3 text-center">
      <h1>{this.props.header}</h1>
      <div className="col-sm-12">
        <form>
          <div className="form-group">
            <input
              className="form-control"
              type="text"
              onChange={this.onInputChange}
              placeholder="Github Username"
              value={this.state.username}
            />
          </div>
        </form>
      </div>
    </div>
  ),
});

2条回答
在下西门庆
2楼-- · 2019-09-13 01:18

Given the lexical scope of 'this' while using arrow functions, i thought it would work.

Then you are misunderstanding the meaning of lexical scope. It does the opposite of what you want.

var foo = () => this;

is almost exactly like

var _temp = this;
var foo = () => _temp;

which means

const PromptContainer = React.createClass({
  getInitialState: () => {
    this;
  },
  onInputChange: (e) => {
    this;
  },
  render: () => {
    this;
  },
});

is

var _temp = this;

const PromptContainer = React.createClass({
  getInitialState: () => {
    _temp;
  },
  onInputChange: (e) => {
    _temp;
  },
  render: () => {
    _temp;
  },
});

so none of your functions ever access this of the function, they access the this of that exists outside the createClass call, which is `undefined.

If you want a short way to write what you want, use concise method syntax:

const PromptContainer = React.createClass({
  getInitialState() {
    this;
  },
  onInputChange(e) {
    this;
  },
  render() {
    this;
  },
});
查看更多
一纸荒年 Trace。
3楼-- · 2019-09-13 01:44

You should bind this to the event handler method:

onChange={this.onInputChange.bind(this)}
查看更多
登录 后发表回答