将组件传递给组件

时间:2021-03-30 18:41:34

标签: reactjs

我有 3 个项目:LoginRegisterAccountFormAccountForm 应该能够接收 LoginRegister 组件作为道具。我对此还是有点陌生​​,因此在尝试了一些不同的事情后在执行上遇到了问题。

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 包裹在 LoginRegister 组件周围?

3 个答案:

答案 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}/>