我有这个免费组件:
我的LoginForm:
import React, { Component } from "react";
import { Pane, TextInputField, Checkbox, Button } from "evergreen-ui";
import { validateEmail, validatePassword } from "./FormValidator";
class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {
passwordErr: {
status: false,
value: ""
},
emailErr: {
status: false,
value: ""
},
email: "",
password: "",
CheckBoxchecked: false
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleCheckbox = this.handleCheckbox.bind(this);
}
handleEmailInput = e => {
const email = e.target.value;
this.setState({ email: email });
};
handlePasswordInput = e => {
const password = e.target.value;
this.setState({ password: password });
};
handleCheckbox() {
this.setState({
CheckBoxchecked: !this.state.CheckBoxchecked
});
}
handleSubmit() {
if (this.checkFormStatus()) {
alert("Form OK");
}
}
checkFormStatus() {
// form validation middleware
const { email, password } = this.state;
const emailErr = validateEmail(email);
const passwordErr = validatePassword(password);
if (!emailErr.status && !passwordErr.status) {
return true;
} else {
this.setState({
emailErr,
passwordErr
});
return false;
}
}
render() {
return (
<Pane padding={15}>
<TextInputField
tabIndex={0}
required
isInvalid={this.state.emailErr.status}
validationMessage={
this.state.emailErr.status ? this.state.emailErr.value : false
}
onChange={this.handleEmailInput}
value={this.state.email}
appearance="neutral"
type="email"
label="Your email-address"
inputHeight={36}
//description="We’ll need your email-address to create an new account"
/>
<TextInputField
required
validationMessage={
this.state.passwordErr.status ? this.state.passwordErr.value : false
}
isInvalid={this.state.passwordErr.status}
onChange={this.handlePasswordInput}
value={this.state.password}
appearance="neutral"
label="Your Password"
type="password"
inputHeight={36}
//description="Create a secure password to protect your account"
/>
<Checkbox
label="Keep me logged in"
checked={this.state.CheckBoxchecked}
onChange={this.handleCheckbox}
/>
</Pane>
);
}
}
export default LoginForm;
我的导出LoginFormButton:
export class LoginFormButton extends Component {
render() {
return (
<Button
appearance="primary"
marginLeft={8}
marginRight={16}
intent="success"
onClick={} //How can i call handleSubmit() from here?
>
Login
</Button>
);
}
}
和我的对话框...
import ReactDOM from "react-dom";
import LoginForm from './LoginForm';
import LoginFormButton from './LoginFormButton';
class LoginDialog extends Components {
render(
return(
<Dialog>
<LoginForm/>
<div className="Footer">
<LoginFormButton/>
</div>
</Dialog>
);
)
}
我将函数handleSubmit()
存储在LoginForm组件中。我想从LoginFormButton调用这些函数。此按钮包含在对话框组件中:
我该怎么做?感谢您的回答和我们的帮助。我是一个初学者,所以我不知道该如何实现。
答案 0 :(得分:1)
看起来,您想要一个LoginForm组件和一个LoginFormButton来处理表单提交。
import React, { Component } from "react";
import { Pane, TextInputField, Checkbox, Button } from "evergreen-ui";
import { validateEmail, validatePassword } from "./FormValidator";
const LoginFormButton = ({ handleSubmit }) => {
return (
<Button
appearance="primary"
marginLeft={8}
marginRight={16}
intent="success"
onClick={() => handleSubmit()} // or just -> onClick={handleSubmit}
>
Login
</Button>
);
}
class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {
passwordErr: {
status: false,
value: ""
},
emailErr: {
status: false,
value: ""
},
email: "",
password: "",
CheckBoxchecked: false
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleCheckbox = this.handleCheckbox.bind(this);
}
handleEmailInput = e => {
const email = e.target.value;
this.setState({ email: email });
};
handlePasswordInput = e => {
const password = e.target.value;
this.setState({ password: password });
};
handleCheckbox() {
this.setState({
CheckBoxchecked: !this.state.CheckBoxchecked
});
}
handleSubmit() {
if (this.checkFormStatus()) {
alert("Form OK");
}
}
checkFormStatus() {
// form validation middleware
const { email, password } = this.state;
const emailErr = validateEmail(email);
const passwordErr = validatePassword(password);
if (!emailErr.status && !passwordErr.status) {
return true;
} else {
this.setState({
emailErr,
passwordErr
});
return false;
}
}
render() {
return (
<Pane padding={15}>
<TextInputField
tabIndex={0}
required
isInvalid={this.state.emailErr.status}
validationMessage={
this.state.emailErr.status ? this.state.emailErr.value : false
}
onChange={this.handleEmailInput}
value={this.state.email}
appearance="neutral"
type="email"
label="Your email-address"
inputHeight={36}
//description="We’ll need your email-address to create an new account"
/>
<TextInputField
required
validationMessage={
this.state.passwordErr.status ? this.state.passwordErr.value : false
}
isInvalid={this.state.passwordErr.status}
onChange={this.handlePasswordInput}
value={this.state.password}
appearance="neutral"
label="Your Password"
type="password"
inputHeight={36}
//description="Create a secure password to protect your account"
/>
<Checkbox
label="Keep me logged in"
checked={this.state.CheckBoxchecked}
onChange={this.handleCheckbox}
/>
<LoginFormButton
handleSubmit={this.handleSubmit}
/>
</Pane>
);
}
}
export default LoginForm;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
1)验证将在LoginForm组件中进行,除非您将this.state.password
和this.state.email
传递给LoginFormButton
组件。我不建议这样做,因为可以在LoginForm组件中处理验证。
2)HandleSubmit函数可以作为来自LoginFormButton
组件的props传递给LoginForm
组件,并且可以在该组件内直接使用。
我建议您在状态变量中遵循JS标准来命名约定(camelCases)。并使用箭头函数,这样就不必显式绑定函数,除非另有说明。
我将您LoginFormButton
更改为无状态组件,因为它不需要状态。这样更好,这也是React社区鼓励的。
答案 1 :(得分:0)
检查以下更正的代码
LoginForm组件
import React, { Component } from "react";
import { Pane, TextInputField, Checkbox, Button } from "evergreen-ui";
import { validateEmail, validatePassword } from "./FormValidator";
class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {
passwordErr: {
status: false,
value: ""
},
emailErr: {
status: false,
value: ""
},
email: "",
password: "",
CheckBoxchecked: false
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleCheckbox = this.handleCheckbox.bind(this);
}
handleEmailInput = e => {
const email = e.target.value;
this.setState({ email: email });
};
handlePasswordInput = e => {
const password = e.target.value;
this.setState({ password: password });
};
handleCheckbox() {
this.setState({
CheckBoxchecked: !this.state.CheckBoxchecked
});
}
handleSubmit() {
if (this.checkFormStatus()) {
alert("Form OK");
}
}
checkFormStatus() {
// form validation middleware
const { email, password } = this.state;
const emailErr = validateEmail(email);
const passwordErr = validatePassword(password);
if (!emailErr.status && !passwordErr.status) {
return true;
} else {
this.setState({
emailErr,
passwordErr
});
return false;
}
}
render() {
return (
<Pane padding={15}>
<TextInputField
tabIndex={0}
required
isInvalid={this.state.emailErr.status}
validationMessage={
this.state.emailErr.status ? this.state.emailErr.value : false
}
onChange={this.handleEmailInput}
value={this.state.email}
appearance="neutral"
type="email"
label="Your email-address"
inputHeight={36}
//description="We’ll need your email-address to create an new account"
/>
<TextInputField
required
validationMessage={
this.state.passwordErr.status ? this.state.passwordErr.value : false
}
isInvalid={this.state.passwordErr.status}
onChange={this.handlePasswordInput}
value={this.state.password}
appearance="neutral"
label="Your Password"
type="password"
inputHeight={36}
//description="Create a secure password to protect your account"
/>
<Checkbox
label="Keep me logged in"
checked={this.state.CheckBoxchecked}
onChange={this.handleCheckbox}
/>
<div className="Footer">
<LoginFormButton handleSubmit={this.handleSubmit} />
</div>
</Pane>
);
}
}
export default LoginForm;
LoginFormButton组件
export class LoginFormButton extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<div>
<Button
appearance="primary"
marginLeft={8}
marginRight={16}
intent="success"
onClick={this.props.handleSubmit}
>
Login
</Button>
</div>
);
}
}
对话框组件
import ReactDOM from "react-dom";
import LoginForm from './LoginForm';
import LoginFormButton from './LoginFormButton';
class LoginDialog extends Components {
render(
return(
<Dialog>
<LoginForm/>
</Dialog>
);
)
}
答案 2 :(得分:0)
我建议您不要将业务逻辑放在按钮组件中。该按钮的唯一工作应该是通知使用它的人该按钮已被单击。通过向按钮传递道具来完成:
export class LoginFormButton extends Component {
render() {
return (
<Button
appearance="primary"
marginLeft={8}
marginRight={16}
intent="success"
onClick={this.props.onClick}
>
Login
</Button>
);
}
}
然后,无论使用什么组件的道具都将是发生业务逻辑的地方。其他解决方案假定登录表单按钮将是登录表单的一部分,这可能也是我的做法。所以我的建议是将这部分从LoginDialog中删除:
<div className="Footer">
<LoginFormButton/>
</div>
将其移至LoginForm.js,并添加回调:
render() {
return (
<Pane padding={15}>
{/* inputs and checkbox components omitted */}
<div className="Footer" onClick={this.handleSubmit}>
<LoginFormButton/>
</div>
</Pane>
)
}
如果由于某种原因您不能将按钮移到表单中,那么您将有更多工作要做。您需要将业务逻辑上移到组件,该组件是按钮和文本输入的共享祖先,即LoginDialog。因此,您将采用LoginForm中当前包含的大多数代码,并将其移至LoginDialog。这包括将状态从LoginForm上移到LoginDialog。然后,LoginForm将需要回调以将相关更改传递回loginDialog,以便对话框可以更新其状态。当按下按钮时,该事件将进入LoginDialog中的handleSubmit。
这种将状态上移到父级的行为在React开发中非常普遍,足以在React的教程页面https://reactjs.org/tutorial/tutorial.html#lifting-state-up中提到。因此,这是解决问题的有效方法,但是在这种情况下,我认为您最好将按钮移至表单中