2016-12-16 84 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