第一次使用React。
总而言之,我需要有一个子级来更新父级组件的状态,尽管我已成功将回调函数传递给了子级,但它的行为与我期望的方式不同。
我有一个组件应用程序,它呈现子组件LoginOverlay。
组件App编写如下:
export default class App extends React.Component{
constructor(props) {
super(props);
this.handleLogin = this.handleLogin.bind(this);
this.state = {
userID:'',
loginState:'waiting',
loginError:'',
};
}
handleLogin(un, pw){
//just try setting a state as if the API call came back with an error code
this.setState({
loginError:'Wrong Password',
})
}
render() {
return (
<div className="App">
{/*login overlay*/}
<LoginOverlay loginError={this.state.loginError} loginState={this.state.loginState} parentCallback={this.handleLogin}/>
UserID:{this.state.userID}
</div>
);
}
}
子组件编写如下:
export default class LoginOverlay extends React.Component{
constructor(props){
super(props);
this.userNameChange=this.userNameChange.bind(this);
this.passwordChange=this.passwordChange.bind(this);
this.submitHandler=this.submitHandler.bind(this);
this.state = {
username:'',
password:'',
loginState:this.props.loginState,
loginError:this.props.loginError,
};
}
userNameChange(event) {
this.setState({
username: event.target.value
});
}
passwordChange(event) {
this.setState({
password: event.target.value
})
}
submitHandler(event) {
event.preventDefault();
if (this.state.username!=='' && this.state.password !=='') {
this.setState({
loginState:'loading',
loginError:'',
})
this.props.parentCallback(this.state.username, this.state.password);
}
else {
this.setState({
loginError:'Fill out the form, please!'
})
}
}
render() {
let bottompane = null;
switch(this.state.loginState) {
case 'waiting':
bottompane = <div className="login-ButtonContainer">
<input
type="submit"
value="Log In"
className="login-button"
/>
</div>
break;
case 'loading':
bottompane = <div className="login-ButtonContainer">
{/*copypasted from loading.io*/}
<div className="lds-spinner"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
</div>
break;
default:
break;
}
let errorText = null;
switch(this.state.loginError) {
case '':
break;
default:
errorText=<div className="login-errortext">{this.state.loginError}</div>
break;
}
return(
<div className="loginOverlay">
<form onSubmit={this.submitHandler} className="login-box">
<label>
Username:
</label>
<input
className="login-field"
type="text"
onChange={this.userNameChange}
/>
<br/>
<label>
Password:
</label>
<input
className="login-field"
type="password"
onChange={this.passwordChange}
/>
<br/>
{bottompane}
{errorText}
</form>
</div>
);
}
}
但是,在我按下了提交按钮并执行了handeLogin之后,loginError状态不会更新(我使用console.log(this.state.loginError)进行检查)。我想知道我的方法是否错误?还是我的语法?
答案 0 :(得分:0)
您不想将道具镜像/复制到这样的状态:
model.train(np.float32(samples3), cv.ml.ROW_SAMPLE, np.float32(responses))
cv2.error: OpenCV(4.1.0) /io/opencv/modules/core/src/matrix.cpp:235: error: (-215:Assertion failed) s >= 0 in function 'setSize'
相反,只要在需要知道该值是什么的地方引用// This is bad news:
this.state = {
loginState: this.props.loginState,
loginError: this.props.loginError,
};
。这就是所谓的“托管组件”,即父组件通过props管理状态。