简体   繁体   English

对子组件反应apss道具或状态

[英]react apss props or state to child component

I need some help about react components. 我需要一些有关React组件的帮助。 I'm newbie on this and I'm making a web app with react and I want to seperate form and container and I did something but not working. 我是新手,我正在用React开发一个Web应用程序,我想分离表单和容器,但我做了一些事情,但是没有用。

LoginFormContainer.jsx 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 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;

Codes give this error : 代码给出此错误:

TypeError: Cannot read property 'email' of null at t.value (LoginFormContainer.jsx:41) TypeError:无法读取t.value处的null属性“ email”(LoginFormContainer.jsx:41)

line41 is : value={this.state.email} line41是:value = {this.state.email}

Where is the problem and how could I pass the props or state ( or both of ) to the child component? 问题出在哪里,如何将道具或状态(或两者)传递给子组件?

In a react component, this.state can only refer to that specific component's internal state. this.state组件中, this.state只能引用该特定组件的内部状态。 React doesn't pass down the state automatically - that's what props are for. React不会自动传递状态-这就是道具的作用。 Here, you could probably get away with passing the entire state object into the LoginFormContainer component. 在这里,您可能会避免将整个状态对象传递到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...
    />
  }
}

Also, another unrelated tip: generally the container component is the one that's concerned about state. 另外,另一个不相关的技巧是:通常,容器组件是与状态有关的组件。 Here it looks like you've got it backwards, so I'd suggest renaming Login to LoginFormContainer and LoginFormContainer to Login . 在这里,您似乎已经倒退了,所以建议您将Login重命名为LoginFormContainer ,将LoginFormContainer重命名为Login

Further reading on props in case any of this is unclear: https://reactjs.org/docs/components-and-props.html 如果不清楚其中任何一项,请进一步阅读道具: https : //reactjs.org/docs/components-and-props.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM