setState 函数在输入值更新时无法按预期更新状态

问题描述 投票:0回答:1

我有一个正在使用自定义输入框组件的组件。这是我的组件:

import React from "react";
import PropTypes from "prop-types";
import phoneValidator from "google-libphonenumber";
import { isStringEmpty, filterPhoneNumber, maskPhoneNumber } from "@lib";
import { InputBoxFormValidation } from "@components/common";

const wrapFormError = message => (<span className="form-error is-visible">{message}</span>);

const validatePhoneNumber = (phone, countryCode) => {
    if (isStringEmpty(phone)) {
        return wrapFormError("This field cannot be empty");
    } else {
        const phoneNumber = filterPhoneNumber(phone);
        let isValid = true;
        if (phoneNumber.length < 2 || phoneNumber.length > 10) {
            isValid = false;
        } else {
            const phoneUtil = phoneValidator.PhoneNumberUtil.getInstance();
            isValid = phoneUtil.isValidNumber(phoneUtil.parseAndKeepRawInput(phoneNumber, countryCode));
        }

        if (!isValid) {
            return wrapFormError("This is not a valid phone number");
        } else {
            return "";
        }
    }
};
class ProfileBusinessInfo extends React.Component {
constructor(props) {
        super(props);
        this.state = {
            filled: false,
            name: "",
            phone: "",
            phoneError: ""
        };
    }
static getDerivedStateFromProps(nextProps) {
        return {
            name: nextProps.data.name,
            phone: nextProps.data.phone,
            phoneError: validatePhoneNumber(nextProps.data.phone, nextProps.data.location.countryCode)
        };
    }
handleChange = (event) => {
        console.log("event object", event);
        this.setState({
            [event.target.name]: event.target.value
        });
        console.log("event.target.name, event.target.value", event.target.name, event.target.value );
        console.log("in handleChange", this.state);
    };
handlePhoneBlur = () => {
        console.log("inside handlePhoneBlur");
        const errorMessage = this.validatePhone(this.state.phone);
        if (isStringEmpty(errorMessage)) {
            let phoneNumber = filterPhoneNumber(this.state.phone);
            phoneNumber = maskPhoneNumber(phoneNumber);

            this.setState({
                phone: phoneNumber,
                phoneError: errorMessage
            });
        } else {
            this.setState({
                phoneError: errorMessage
            });
        }
    };

    validatePhone = (phone) => {
        const { countryCode } = this.state;
        validatePhoneNumber(phone, countryCode);
    }
 render () {
const { isSignup, cancelForm } = this.props;
        const { name, address1, address2, city, state, zip, countryCode } = this.state;
        console.log("state in return statement", this.state);

        return (
 <div>
                            <InputBoxFormValidation
                                label="Business Phone"
                                type="tel" name="phone" id="phone" placeholder="(XXX) XXX-XXXX" value={this.state.phone}
                                onChange={this.handleChange}
                                validations={[this.validatePhone]}
                                className="form-control"
                                onBlurHandler={this.handlePhoneBlur}
                            />
                        </div>
)
}
}
export default ProfileBusinessInfo;

这是我的InputBoxFormValidation 组件:

import React from "react";
import PropTypes from "prop-types";

import Styles from "./InputBoxFormValidation.scss";
import Input from "react-validation/build/input";

class InputBoxFormValidation extends React.Component {
    constructor (props) {
        super(props);
        this.state = {
            focused: false
        };
    }

    onFocushandler = () => {
        this.setState({
            focused: true
        });
        if (this.props.onFocushandler) {
            this.props.onFocushandler();
        }
    }

    onBlurHandler = () => {
        this.setState({
            focused: false
        });
        if (this.props.onBlurHandler) {
            this.props.onBlurHandler();
        }
    }

    onChangeHandler = (e) => {
        if (this.props.onChangeHandler) {
            this.props.onChangeHandler(e);
        }
    }

    render() {
        const { label, name, errorMessage, autoComplete } = this.props;
        const isActive = (this.props.value || this.state.focused);
        const containerClass = `${Styles.inputContainer} ${errorMessage ? Styles.error : ""} ${isActive ? Styles.active : ""}`;
        const inputProps = {...this.props};
        delete inputProps.onBlurHandler;
        delete inputProps.onFocushandler;
        delete inputProps.placeholder;
        delete inputProps.children;

        return (
            <div className={containerClass}>
                <Input
                    {...inputProps}
                    onFocus={this.onFocushandler}
                    onBlur={this.onBlurHandler}
                    autoComplete={autoComplete || "on"}
                />
                <label className={Styles.labelContainer} htmlFor={name}>
                    {label}
                </label>
                {this.props.children}
            </div>
        );
    }
}

InputBoxFormValidation.propTypes = {
    onChangeHandler: PropTypes.func,
    onFocushandler: PropTypes.func,
    onBlurHandler: PropTypes.func,
    onKeyDown: PropTypes.func,
    placeholder: PropTypes.string,
    label: PropTypes.string,
    type: PropTypes.string,
    name: PropTypes.string,
    errorMessage: PropTypes.string,
    maxLength: PropTypes.number,
    minLength: PropTypes.number,
    value: PropTypes.string,
    children: PropTypes.node,
    autoComplete: PropTypes.string
};

export default InputBoxFormValidation;

以下是上面代码中使用的 lib 函数:

export const isStringEmpty = (str) => {
    return str == "" || str == undefined || str == null;
};
export const filterPhoneNumber = (phone) => {
    return phone.replace(/\D/g, "");
};
export const maskPhoneNumber = (phone) => {
    let phoneNumber = phone.match(/(\d{3})(\d{3})(\d{4})/);
    return "(" + phoneNumber[1] + ") " + phoneNumber[2] + "-" + phoneNumber[3];
};

这里的问题是当我尝试从浏览器更改输入字段中的值时,状态不会更新。在渲染方法中记录状态时,我继续仅获取初始状态。 谁能指出我是否遗漏了什么?

javascript reactjs validation input setstate
1个回答
0
投票

您需要添加

onChange
事件

<div className={containerClass}>
     <Input
        {...inputProps}
        onFocus={this.onFocushandler}
        onBlur={this.onBlurHandler}
        onChange={this.onChangeHandler}
        autoComplete={autoComplete || "on"}
      />
      <label className={Styles.labelContainer} htmlFor={name}>
        {label}
      </label>
      {this.props.children}
</div>
© www.soinside.com 2019 - 2024. All rights reserved.