我需要一些关于反应组件的帮助。我是这方面的新手,我正在制作一个带有反应的网络应用程序,我想分离表单和容器,我做了一些但没有工作。
LoginFormContainer.jsx
import React from "react";
import {
Row,
Col,
Card,
CardTitle,
Form,
FormGroup,
Button,
Label,
Input,
FormText
} from "reactstrap";
class LoginFormContainer extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Row>
<Col
md={{ size: 8, offset: 2 }}
sm={{ size: 8, offset: 2 }}
lg={{ size: 6, offset: 3 }}
>
<Card body className="auth-card">
<CardTitle className="text-center mb-4">
Giriş Yap
</CardTitle>
<Form onSubmit={this.handleSubmit}>
<FormGroup row>
<Label sm="2" className="form-control-label">
Email
</Label>
<Col sm="10">
<Input
type="email"
name="email"
value={this.state.email}
onChange={event =>
this.handleUserInput(event)
}
className={`${this.errorClass(
"email"
)}`}
/>
{this.state.formErrors.email ? (
<div className="invalid-feedback">
{this.state.formErrors.email}
</div>
) : (
""
)}
</Col>
</FormGroup>
<FormGroup row>
<Label sm="2" className="form-control-label">
Şifre
</Label>
<Col sm="10">
<Input
type="password"
name="password"
value={this.state.password}
onChange={event =>
this.handleUserInput(event)
}
className={`${this.errorClass(
"password"
)}`}
/>
{this.state.formErrors.password ? (
<div className="invalid-feedback">
{this.state.formErrors.password}
</div>
) : (
""
)}
</Col>
</FormGroup>
<Button
color="primary"
className="float-right"
type="submit"
disabled={!this.state.formValid}
>
{this.state.button[this.state.formSubmit]}
</Button>
</Form>
</Card>
</Col>
</Row>
);
}
}
export default LoginFormContainer;
LoginForm.jsx
import React from "react"
import LoginFormContainer from './LoginFormContainer'
class Login extends React.Component {
constructor(props) {
super(props);
this.handleUserInput = this.handleUserInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {
email: "",
password: "",
formErrors: { email: "", password: "" },
emailValid: false,
passwordValid: false,
formValid: false,
formSubmit : 'normal',
button: {
normal: "Giriş Yap",
loading: <i className="fa fa-fw fa-spin fa-spinner"></i>
}
};
}
handleSubmit(e) {
this.setState({
formSubmit: 'loading'
});
e.preventDefault();
}
handleUserInput(e) {
const name = e.target.name;
const value = e.target.value;
this.setState({ [name]: value }, () => {
this.validateField(name, value);
});
}
validateField(fieldName, value) {
let fieldValidationErrors = this.state.formErrors;
let emailValid = this.state.emailValid;
let passwordValid = this.state.passwordValid;
switch (fieldName) {
case "email":
emailValid = value.match(
/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i
);
fieldValidationErrors.email = emailValid ? "" : " is invalid";
break;
case "password":
passwordValid = value.length >= 6;
fieldValidationErrors.password = passwordValid
? ""
: " is too short";
break;
default:
break;
}
this.setState(
{
formErrors: fieldValidationErrors,
emailValid: emailValid,
passwordValid: passwordValid
},
this.validateForm
);
}
validateForm() {
this.setState({
formValid: this.state.emailValid && this.state.passwordValid
});
}
errorClass(key) {
return this.state[key].length > 0 &&
this.state.formErrors[key].length > 0
? "is-invalid"
: "";
}
render() {
return <LoginFormContainer />;
}
}
export default Login;
代码会出现此错误:
TypeError:无法在t.value读取null的属性'email'(LoginFormContainer.jsx:41)
line41是:value = {this.state.email}
问题出在哪里?如何将道具或州(或两者)传递给子组件?
答案 0 :(得分:0)
在反应组件中,this.state
只能引用该特定组件的内部状态。 React并没有自动传递状态 - 这就是道具的用途。在这里,您可以将整个状态对象传递给LoginFormContainer组件。
class Login extends React.Component {
// ...
render() {
return <LoginFormContainer formState={this.state} />
}
}
class LoginFormContainer {
render() {
// instead of this.state.email, access this.props.formState.email
// so your input would look like this:
<Input
type="email"
name="email"
value={this.props.formState.email}
// other props...
/>
}
}
另外,另一个不相关的提示:通常容器组件是关注状态的组件。在这里看起来你已经倒退了,所以我建议将Login
重命名为LoginFormContainer
,将LoginFormContainer
重命名为Login
。
如果有任何不明确的话,请继续阅读道具:https://reactjs.org/docs/components-and-props.html