【问题标题】:Trying to convert React.CreateClass to extends React.Component试图将 React.CreateClass 转换为扩展 React.Component
【发布时间】:2016-12-16 12:46:59
【问题描述】:

我正在尝试将使用 React.CreateClass 编写的示例转换为扩展 React.Component 但事件处理程序没有获得状态并且对我失败。有人可以阐明我做错了什么吗?

工作样本:

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>
    );
}
});

我试图从中得到什么:

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>)
        ;
    }
}

表单域:

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 对象,看起来还有更多。

这可能是由于 Babel 将其转换为其他内容,还是因为我正在扩展的类 (React.Component)。我正在迈出进入 React.js 世界的第一步,并且已经运行了很多东西,但这对我来说并不奏效,我也不清楚为什么不这样做。

我用来转译的 gulpfile:

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');
});

【问题讨论】:

    标签: javascript reactjs babeljs


    【解决方案1】:

    对于类方法,this 不会自动绑定到类(构造函数和 React 生命周期方法除外)。

    解决方案 1

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

    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 功能,您可能需要使用 correct plugin 配置 Babel。

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

    解决方案 3

    使用自动绑定第三方库为您执行此操作:

    【讨论】:

    • 似乎解决方案对我有用。然而,解决方案 2 并没有被 JSX 接受。
    • 哎呀,忘了去掉花括号。更新了我的答案。此外,您可能需要 Babel,因为箭头功能仅适用于 ES6。
    • 我稍后会尝试那个。我也尝试过将直接作为属性传递但没有成功:stackoverflow.com/questions/41186015/react-js-passing-in-props.
    猜你喜欢
    • 2017-04-03
    • 2016-07-15
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 2019-09-12
    相关资源
    最近更新 更多