如果setState之前发生过,React不会触发onClick

时间:2019-01-30 16:15:50

标签: javascript reactjs

我有一个带有受控输入元素的表格。输入可能具有验证,并且它们正在onBlur上发生,并且如果用户在“提交”按钮上进行了onClick。如果验证状态在检查后发生更改(删除或添加错误),则它将以React setState的形式存储在React状态。如果验证状态未更改(未添加错误或未删除),则提交立即发生。如果出现错误,但单击后验证成功,则onBlur会触发并引起状态更改,并且甚至不会触发onClick,因此只需单击两次即可提交。

    

    completeProcess = (val, process, maxLen) => process(val).substr(0, maxLen)
    //called inside render
    renderInputs = () => this.props.inputs.map(input => {
        const {
            id,
            validation,
            required = true,
            label,
            initValue = "",
            className = "",
            placeholder = "",
            type = "text",
            tag = "input",
            options = [],
            process = v => v,
            minLen = 0,
            maxLen = 20000
        } = input;

        const value = this.state[id] ? this.state[id].value : initValue;
        const error = this.state[id] ? this.state[id].error : null;

        const onBlur = () => {
            console.log("blur")
            this.setState({ [id]: {
                ...this.state[id],
                error: validate({value, validation, required, minLen})
            }});
        };
        const onChange = ({ target: { value: newValue }}) => this.setState(
            { [id]: {
                ...this.state[id],
                value: process(newValue)
            }}
        );
        return (
            <Input
                className={className}
                label={label}
                placeholder={placeholder}
                value={value}
                onBlur={onBlur}
                onChange={onChange}
                type={type}
                tag={tag}
                options={options}
                key={id}
                id={id}
                error={error}
            />
        );
    })
    
    //called on submit button click
        handleSubmit = () => {
        console.log("submit")
        const inputProps = this.state;
        const errors = {};
        const processedValues = {};

        this.props.inputs.map(
            ({
                id,
                required = true,
                validation,
                process = v => v,
                minLen = 0,
                maxLen = 20000
            }) => {
                    const { value } = inputProps[id];
                    errors[id] = validate(
                        {value, validation, required, minLen}
                    );
                    processedValues[id] = this.completeProcess(
                        value, process, maxLen
                    );
            }
        );

        const errorFree = Object.values(errors).every(e => !e);

        if (errorFree) {
            this.props.onSubmit(processedValues);
        } else {
            const newState = {};

            Object.keys(inputProps).forEach(id => {
                const { value } = inputProps[id];
                const error = errors[id];
                newState[id] = { value, error };
            });

            this.setState(newState);
        }
    }

0 个答案:

没有答案