在反应挂钩中多次渲染组件

时间:2020-09-29 16:29:02

标签: javascript reactjs react-native react-redux react-hooks

由于我对钩子反应还很陌生,所以我无法理解现有代码的某些部分,为什么当属性状态更改时,我的组件会多次重新渲染。下面是组件代码。我添加了console.log以便更好地理解。

import React, { useState, useRef } from 'react';
import api from '../api/api';
import { UPLOAD_DATA } from '../api/urls';
import Alert from '../layout/alerts/Alerts';



const StudentDetailsView = ({ symbol }) => {
    console.log("inside StudentDetailsView");
    const initialState = {
        form: {
            qualification: symbol.qualification,
            profession: symbol.profession
        }
    };

    const [loading, setLoading] = useState(false);
    const [errors, setErrors] = useState(null);
    const [editFlag, setEditFlag] = useState(false);
    const [inputs, setInputs] = useState(initialState);
    console.log("before dataUpdated");
    const [dataUpdated, setDataUpdated] =useState(false);
    console.log("after dataUpdated");
    const formRef = useRef(null);

    const handleCancel = () => {
        setEditFlag(false);
        setInputs(initialState);
    };

    const handleSubmit = (e) => {
        console.log("inside handleSumbit");
        const form = formRef.current;
        e.preventDefault();
        e.stopPropagation();
        form.classList.add('was-validated');

        if (form.checkValidity()) {
            callback();
        }
        
    };

    const callback = ()=> {
        setLoading(true);
        const formData = new FormData();
        formData.append('model', new Blob([JSON.stringify(inputs.form)], {
            type: 'application/json'
        }));

        api.multipartEdit(UPLOAD_DATA, formData)
            .then(response => {
                setInputs(inputs => ({
                    ...inputs,
                    form: {
                        qualification: response.data.qualification,
                        profession: response.data.profession
                    }
                }));
                setErrors(null);
                setDataUpdated(true);
            })
            .catch(error => {
                setErrors(error);
            })
            .finally(() => {
                setLoading(false);
                setEditFlag(false);
            });
    }

    const handleInputChange = (event) => {
        event.persist();
        setInputs(inputs => ({
            ...inputs,
            form: {
                ...inputs.form,
                [event.target.name]: event.target.value
            }
        }));
    }

    return (
        <div>
            {
                errors &&
                <Alert type={errors.type} title={errors.title} description={errors.description} id="alert" />
            }

            <div >
                {editFlag ? (
                    <div >
                    </div>
                ) :
                    (<div className="edit">
                        <button type="button" onClick={() => setEditFlag(!editFlag)}>
                            Edit
                        </button>
                    </div>)
                }
            </div>
            <div>
                <form className="needs-validation" onSubmit={handleSubmit} ref={formRef} noValidate>
                    {
                        editFlag ? (<div className="update-cancel-button">
                            <button className="btn btn-primary" type="submit" >
                                {loading ? (
                                    <div className="spinner-border uxf-spinner-border-sm">
                                        <span className="sr-only">Loading...</span>
                                    </div>) : 'Update'}
                            </button>
                            <button className="btn btn-secondary cancel-button" type="button" onClick={handleCancel}>Cancel</button>
                        </div>) : <div></div>
                    }
                    <dl className="uxf-dl uxf-dl-horizontal">
                        <dt>Name</dt>
                        <dd>{symbol.name}</dd>
                        
                        <dt>Age</dt>
                        <dd>{symbol.age}</dd>

                        <dt>Qualification</dt>
                        {editFlag ?
                            (<dd>
                                <textarea className="form-control" name="qualification" id="qualification"
                                    value={inputs.form.qualification}
                                    onChange={handleInputChange}
                                    maxLength="255"></textarea>
                                <div className="invalid-feedback">
                                    Please provide a Qualification.
                                </div>
                            </dd>)
                            :
                            (<dd>{dataUpdated ? (inputs.form.qualification ? inputs.form.qualification : '-') : (symbol.qualification ? symbol.qualification : '-')}</dd>)
                        }
                        <dt>Profession</dt>
                        {editFlag ?
                            (<dd>
                                <textarea className="form-control" name="profession" id="profession"
                                    value={inputs.form.profession}
                                    onChange={handleInputChange}
                                    minLength="1"
                                    maxLength="1000"
                                    required></textarea>
                                <div className="invalid-feedback">
                                    Please provide a Profession.
                                </div>
                            </dd>)
                            :
                            (<dd>{dataUpdated ? inputs.form.profession : symbol.profession}</dd>)
                        }
                    </dl>
                </form>
            </div>
        </div>
    );
}

export default StudentDetailsView;

由于我的组件被重新渲染,因此在代码 (例如,dataUpdated) 中设置的状态值将再次使用默认值进行更新,再次。如何防止这种情况发生?请查看下面的图片以更好地了解。

enter image description here

(将编辑组件的模型显示为实际数据显示在实际编辑组件中)

enter image description here

我单击了一次编辑按钮,然后单击了取消按钮,这就是生成的控制台日志。

enter image description here

0 个答案:

没有答案