我有 3 个项目:Login
、Register
和 AccountForm
。 AccountForm
应该能够接收 Login
或 Register
组件作为道具。我对此还是有点陌生,因此在尝试了一些不同的事情后在执行上遇到了问题。
AccountForm
:
class AccountForm extends Component {
render() {
return (
<Container>
<Row>
<Col md="6" className="mx-auto d-flex align-items-center">
<Container className="form-container">
<Row>
<Image src={"/static/frontend/images/digibrain-bubble-bg-black-thin.svg"}
alt="DigiBrain logo"
fluid
/>
</Row>
<Row className="mt-4">
<Col>
<Container>
{ this.props.form } // this is where I would like to pass the forms into.
</Container>
</Col>
</Row>
</Container>
</Col>
</Row>
</Container>
);
}
}
Login
:
class Login extends Component {
state = {
username: "",
password: "",
}
static propTypes = {
login: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool
}
onSubmit = e => {
e.preventDefault();
this.props.login(this.state.username, this.state.password)
}
onChange = e => this.setState({
[e.target.name]: e.target.value
});
render() {
if (this.props.isAuthenticated) {
return <Redirect to="/dashboard"/>;
}
const {username, password} = this.state;
return (
<>
<FormGroup>
<h3 className="form-header">Sign In</h3>
</FormGroup>
<Form onSubmit={this.onSubmit}>
<FormGroup>
<label>Username</label>
<input
type="text"
className="form-control"
name="username"
onChange={this.onChange}
value={username}
/>
</FormGroup>
<FormGroup>
<label>Password</label>
<input
type="password"
className="form-control"
name="password"
onChange={this.onChange}
value={password}
/>
<Container className="mb-2">
<p className="text-right">
<small>
<Link to="/register">Forgot Password?</Link>
</small>
</p>
</Container>
</FormGroup>
<FormGroup>
<Button
type="submit"
className="btn btn-primary btn-lg btn-block">
<i className="fas fa-sign-in-alt p-1"/>
Sign In
</Button>
<p className="text-center text-muted">
<small>
By signing in you agree to our <Link to="/terms-of-service">Terms
of
Service</Link> and <Link to="/privacy-policy">Privacy
Policy</Link>
</small>
</p>
<p className="text-center text-muted">
Need an account? <Link to="/register">Sign Up</Link>
</p>
</FormGroup>
</Form>
</>
);
}
}
.. 和 Register
是与 Login
类似的形式,所以不需要发布它......
我的路线如下所示:
<Route exact path='/register/' component={Register}/>
<Route exact path='/login/' component={Login}/>
如何将 AccountForm
包裹在 Login
和 Register
组件周围?
答案 0 :(得分:1)
您可以使用 arrow function
创建动态组件并使用 render
属性发送您想要的任何参数。
<Route exact path='/register/' render={() => <AccountForm form={Register} />}/>
<Route exact path='/login/' render={() => <AccountForm form={Login} />}/>
这次您将从 component
切换到 render
。顾名思义,render 可以接收一个函数来内联渲染您的新组件。这在确定此路线的最终组件时提供了更大的灵活性。
您可以在此处阅读有关 Route
及其 render
道具的更多信息:https://reactrouter.com/web/api/Route/render-func
答案 1 :(得分:1)
我们可以创建 HOC - AccountForm 并将其应用于“登录”和“注册”组件
可供参考 - https://reactjs.org/docs/higher-order-components.html
答案 2 :(得分:0)
虽然其他答案很有帮助,但我找到了一个更简单的解决方案,它允许我将代码执行保持在较低级别。我必须像孩子一样传递表格,就像我最初尝试做的那样:
AccountForm
:
class AccountForm extends Component {
render() {
return (
<Container>
<Row>
<Col md="6" className="mx-auto d-flex align-items-center">
<Container className="form-container">
<Row>
<Image src={"/static/frontend/images/digibrain-bubble-bg-black-thin.svg"}
alt="DigiBrain logo"
fluid
/>
</Row>
<Row className="mt-4">
<Col>
<Container>
{ this.props.children }
</Container>
</Col>
</Row>
</Container>
</Col>
</Row>
</Container>
);
}
}
然后我不得不将 Login
组件包装在 <AccountForm>
标签中:
class Login extends Component {
state = {
username: "",
password: "",
}
static propTypes = {
login: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool
}
onSubmit = e => {
e.preventDefault();
this.props.login(this.state.username, this.state.password)
}
onChange = e => this.setState({
[e.target.name]: e.target.value
});
render() {
if (this.props.isAuthenticated) {
return <Redirect to="/dashboard"/>;
}
const {username, password} = this.state;
return (
<AccountForm>
<FormGroup>
<h3 className="form-header">Sign In</h3>
</FormGroup>
<Form onSubmit={this.onSubmit}>
<FormGroup>
<label>Username</label>
<input
type="text"
className="form-control"
name="username"
onChange={this.onChange}
value={username}
/>
</FormGroup>
<FormGroup>
<label>Password</label>
<input
type="password"
className="form-control"
name="password"
onChange={this.onChange}
value={password}
/>
<Container className="mb-2">
<p className="text-right">
<small>
<Link to="/register">Forgot Password?</Link>
</small>
</p>
</Container>
</FormGroup>
<FormGroup>
<Button
type="submit"
className="btn btn-primary btn-lg btn-block">
<i className="fas fa-sign-in-alt p-1"/>
Sign In
</Button>
<p className="text-center text-muted">
<small>
By signing in you agree to our <Link to="/terms-of-service">Terms
of
Service</Link> and <Link to="/privacy-policy">Privacy
Policy</Link>
</small>
</p>
<p className="text-center text-muted">
Need an account? <Link to="/register">Sign Up</Link>
</p>
</FormGroup>
</Form>
</AccountForm>
);
}
}
这使我能够在使 Route
可重复使用的同时保持 AccountForm
不变:
<Route exact path='/login/' component={Login}/>