2016-12-16 81 views
0

我试图将使用React.CreateClass编写的示例转换为扩展React.Component,但事件处理程序未获取状态并且失败。有人可以阐明我做错了什么吗?试图将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>) 
     ; 
    } 
} 

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

调试时,我注意到,在这两种情况下,thisthis.setState(state);是完全不同的东西。在Form5中,它只提供状态,而在Form4中它是一个完整的React对象,它看起来更像它。

这可能是由于巴贝尔把它转移到别的东西上,或者是因为我正在扩展的类(React.Component)。我正在进入React.js世界的第一步,已经有很多东西在运行,但这并不适合我,我也没有清楚地指出为什么不这样做。

我使用transpile的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'); 
}); 

回答

1

随着类的方法,该this不会自动绑定到类(除了构造和阵营生命周期方法)。

溶液1

绑定的构造内的功能,以这样的:

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

使用自动绑定第三方库,为你这样做:

+0

似乎解决方案的工作为我。然而,解决方案2并未被JSX所接受。 – XIII

+0

Oups,忘了去掉大括号。更新了我的答案。您也可能需要Babel,因为箭头功能仅适用于ES6。 – mbernardeau

+0

稍后我会试一试。我也试过它通过直接作为属性,但没有成功:http://stackoverflow.com/questions/41186015/react-js-passing-in-props。 – XIII