簡體   English   中英

對子組件反應apss道具或狀態

[英]react apss props or state to child component

我需要一些有關React組件的幫助。 我是新手,我正在用React開發一個Web應用程序,我想分離表單和容器,但我做了一些事情,但是沒有用。

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}

問題出在哪里,如何將道具或狀態(或兩者)傳遞給子組件?

this.state組件中, 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM