尝试将React.CreateClass转换为扩展React.Component [英] Trying to convert React.CreateClass to extends React.Component

查看:109
本文介绍了尝试将React.CreateClass转换为扩展React.Component的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将用React.CreateClass编写的样本转换为扩展React.Component,但是事件处理程序无法获取状态并且对我失败.有人可以告诉我我在做什么错吗?

I'm trying to convert a sample written with React.CreateClass to extends React.Component but the eventhandler doesn't get the state and fails on me. Can someone shed some light on what I'm doing wrong?

工作示例:

var Form4 = React.createClass({
    getInitialState: function () {
        return {
            username: '',
            password: ''
        }
    },
    handleChange: function (key) {
        return function (e) {
            var state = {};
            state[key] = e.target.value;
            this.setState(state);
        }.bind(this);
    },
    resetForm: function() {
        this.setState({username:'', password: ''});
    },
    changeFunkyShizzle: function() {
        this.setState({
            username: 'Tom',
            password: 'Secret'
        });
    },
    updateToServer(e) {
        console.log('update to server....');
        console.log(this.state);
        e.preventDefault();
    },
    render: function(){
        console.log(JSON.stringify(this.state, null, 4));
        return (
          <div>
            <FormFields unamepwd={this.state} handleChange={this.handleChange} updateChanges={this.updateToServer} />

        <pre>{JSON.stringify(this.state, null, 4)}</pre>
        <button onClick={this.changeFunkyShizzle}>Change is near...</button>
        <button onClick={this.resetForm}>Reset all the things!</button>
      </div>
    );
}
});

我试图从中得到的东西:

What I tried to make from it:

class Form5 extends React.Component {
    constructor() {
        super();
        this.state = {
            username: '',
            password: ''
        };
    }
    handleChange(key) {
        return function (e) {
            var state = {};
            state[key] = e.target.value;
            this.setState(state);
        }.bind(this);
    }
    changeFunkyShizzle() {
        this.setState({
            username: 'Tom',
            password: 'Secret'
        });
    }
    render() {
        let self = this;
        console.log(JSON.stringify(this.state, null, 4));
        return (
            <div>
            <FormFields unamepwd={this.state} handleChange={self.handleChange} updateChanges={self.updateToServer} />

                <pre>{JSON.stringify(this.state, null, 4)}</pre>
                <button onClick={this.changeFunkyShizzle}>Change is near...</button>
                <button onClick={this.resetForm}>Reset all the things!</button>
              </div>)
        ;
    }
}

Formfields:

Formfields:

var FormFields = React.createClass({
    render: function() {
        const upwd = this.props.unamepwd;
        return(
        <form>
            Username: <input
        value={upwd.username}
        onChange={this.props.handleChange('username')} />
  <br />
            Password: <input type="password"
        value={upwd.password}
        onChange={this.props.handleChange('password')} />
  <button onClick={this.props.updateChanges}>Go!</button>
</form>
        );
    }
});

调试时,我注意到在两种情况下,this.setState(state);中的this都是完全不同的.在Form5中,它仅提供状态,而在Form4中,它是一个完整的React对象,看起来还有更多状态.

When debugging I noticed that in both cases the this in this.setState(state); is something completely different. In Form5 it only provides the state while in Form4 it's a complete React object it seems with way more on it.

这可能是由于Babel将其转换为其他东西还是由于我正在扩展的类(React.Component).我正在迈入React.js领域的第一步,已经有很多东西在运行,但这对我来说并不奏效,我也没有明确的指示为什么不这样做.

Could this be due to Babel transpiling it to something else or because of the class I'm extending (React.Component). I'm taking my first steps into the React.js world and already got quite some stuff running but this is not working out for me and I don't have a clear indication why not.

我用来转译的gulpfile:

The gulpfile I use to transpile:

var gulp = require('gulp');
var babel = require('gulp-babel');
var sourceMaps = require('gulp-sourcemaps');

gulp.task('transpile', function () {
    gulp.src('source/**.jsx')
        .pipe(sourceMaps.init())
        .pipe(babel({ "presets": "react" }))
        .pipe(babel({ "presets": "es2015" }))
        .pipe(sourceMaps.write('.'))
        .pipe(gulp.dest('app/'));
});

gulp.task('watchers', function () {
    gulp.watch('source/**.jsx', ['transpile']);
});

gulp.task('default', ['watchers'], function () {
    console.log('gulp default task running');
});

推荐答案

使用类方法,this不会自动绑定到类(构造函数和React lifecyle方法除外).

With class methods, the this is not automatically bound to class (except for constructor and React lifecyle methods).

解决方案1 ​​

在构造函数中将函数绑定到此:

Bind the functions to this inside the constructor:

constructor() {
    super();
    this.state = {
        username: '',
        password: ''
    };
    this.handleChange = this.handleChange.bind(this);
    this.changeFunkyShizzle= this.changeFunkyShizzle.bind(this);
}
handleChange(key) {
    return function (e) {
        var state = {};
        state[key] = e.target.value;
        this.setState(state);
    }.bind(this);
}
changeFunkyShizzle() {
    this.setState({
        username: 'Tom',
        password: 'Secret'
    });
}

解决方案2

使用箭头功能.由于这是ES6功能,因此您可能需要使用正确的插件来配置Babel .

Use arrow functions. As this is a ES6 feature, you might need to configure Babel with the correct plugin.

handleChange = (key) => (e) => {
  var state = {};
  state[key] = e.target.value;
  this.setState(state);
}

changeFunkyShizzle = () => {
   this.setState({
       username: 'Tom',
       password: 'Secret'
   });
}

解决方案3

使用自动绑定的第三方库为您完成此操作:

Use an autobinding third party library to do this for you:

  • https://github.com/cassiozen/React-autobind
  • https://github.com/andreypopp/autobind-decorator

这篇关于尝试将React.CreateClass转换为扩展React.Component的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆