我正在尝试转换使用React.CreateClass编写的示例来扩展React.Component但是eventhandler没有获得状态并且对我失败。有人能否解释我做错了什么?
工作样本:
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>
);
}
});
调试时我注意到在this
中this.setState(state);
中的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');
});
完全不同。在Form5中它只提供状态,而在Form4中它是一个完整的React对象,它看起来更多。
这可能是由于Babel将其转换为其他内容或因为我正在扩展的类(React.Component)。我正在迈出React.js世界的第一步并且已经运行了很多东西,但这对我来说并不合适,而且我没有明确指示为什么不这样做。
我用来转换的gulp文件:
@RunWith(AndroidJUnit4.class)
public class Regression extends BaseTest {
private static final String TAG = TestConstants.TAGPRETEXT + Regression.class.getSimpleName() + " ";
private ActivityTestRule<MainActivity> activityTestRule;
private TestName testName;
@Rule
public RuleChain chain = RuleChain
.outerRule(activityTestRule = new ActivityTestRule<>(MainActivity.class))
.around(testName = new TestName());
@Override
public <MainActivity extends AppCompatActivity> MainActivity getActivity() {
return (MainActivity) activityTestRule.getActivity();
}
@Override
public TestName getTestName() {
return testName;
}
@Test
public void addBasalProgram24Segments() {
String programName = "testing" + System.currentTimeMillis() / 1000;
try {
new Main()
.doBasal()
.createBasalSegment(new float[]{1.15f, 14.55f, 0.05f, 12.05f, 19.05f, 21.5f, 20, 1.85f, 10.0f, 1, 2, 4, 15, 26.05f, 10, 30, 15, 4, 25, 15, 5, 12, 10, 20}, programName, new Random().nextInt(5), activityTestRule)
.verifyBasalProgramExist(programName);
} catch (MyEspressoException e) {
testFailRoutine(e);
}
}
}
答案 0 :(得分:1)
使用类方法时,this
不会自动绑定到类(构造函数和React生命周期方法除外)。
解决方案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
使用自动绑定第三方库为您执行此操作: