Javascript 在react钩子中多次重新渲染组件
由于我对react钩子相当陌生,我无法理解现有代码的某些部分,为什么当属性的状态发生更改时,组件会多次重新呈现。下面是组件代码。为了更好地理解,我添加了console.logJavascript 在react钩子中多次重新渲染组件,javascript,reactjs,react-native,react-redux,react-hooks,Javascript,Reactjs,React Native,React Redux,React Hooks,由于我对react钩子相当陌生,我无法理解现有代码的某些部分,为什么当属性的状态发生更改时,组件会多次重新呈现。下面是组件代码。为了更好地理解,我添加了console.log import React, { useState, useRef } from 'react'; import api from '../api/api'; import { UPLOAD_DATA } from '../api/urls'; import Alert from '../layout/alerts/Aler
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;
import React,{useState,useRef}来自“React”;
从“../api/api”导入api;
从“../api/URL”导入{UPLOAD_DATA};
从“../layout/alerts/alerts”导入警报;
const StudentDetailsView=({symbol})=>{
日志(“内部学生详细信息视图”);
常量初始状态={
表格:{
资格:symbol.资格,
职业:符号
}
};
const[loading,setLoading]=useState(false);
const[errors,setErrors]=useState(null);
const[editFlag,setEditFlag]=useState(false);
常量[inputs,setInputs]=useState(初始状态);
console.log(“数据更新前”);
const[dataUpdated,setDataUpdated]=useState(false);
console.log(“数据更新后”);
const formRef=useRef(null);
常量handleCancel=()=>{
setEditFlag(假);
设置输入(初始状态);
};
常量handleSubmit=(e)=>{
console.log(“内把手sumbit”);
const form=formRef.current;
e、 预防默认值();
e、 停止传播();
form.classList.add('was-validated');
if(form.checkValidity()){
回调();
}
};
常量回调=()=>{
设置加载(真);
const formData=new formData();
append('model',新Blob([JSON.stringify(inputs.form)]{
键入:“application/json”
}));
api.multipartEdit(上传数据,formData)
。然后(响应=>{
设置输入(输入=>({
…输入,
表格:{
资格:响应、数据、资格,
职业:response.data.profession
}
}));
设置错误(空);
setDataUpdated(true);
})
.catch(错误=>{
设置错误(错误);
})
.最后(()=>{
设置加载(假);
setEditFlag(假);
});
}
常量handleInputChange=(事件)=>{
event.persist();
设置输入(输入=>({
…输入,
表格:{
…输入.form,
[event.target.name]:event.target.value
}
}));
}
返回(
{
错误&&
(显示编辑组件的实体模型,与实际编辑组件中显示的实际数据相同)
我单击了编辑按钮一次,然后单击了取消按钮一次,这是生成的控制台日志
你的应用程序是否使用React的“严格模式”?如果是这样,你的答案是每次它重新启动时,你的动作处理程序都会在内存中重新制作,请在React文档上签出useCallback或useMemo。