#javascript #reactjs #react-hooks #use-effect #use-state
Вопрос:
Я разрабатываю страницу react для стоматологической медицины в рамках проекта uni, и я довольно новичок в react и javascript.
Теперь у меня есть страница декларации о состоянии здоровья с кучей переключателей, которые меняют цвет в зависимости от их состояния. Когда пользователь входит в систему и заходит на страницу своей декларации о состоянии здоровья, я хочу, чтобы предыдущие значения, которые он сохранил, были загружены один раз, а затем только в том случае, если он нажмет обновить.
мой функциональный код выглядит так:
import { useState, useEffect } from "react";
import authHeader from "../../security/AuthHeader";
import axios from "axios";
import "../ToggleSwitch.css";
const ToggleSwitch = (userid) => {
const API_URL = "http://localhost:8081/api/doh/";
const switchState = {
asthma: "off",
infectiousDisease: "off",
bleedingDisorder: "off",
cancer: "off",
diabetes: "off",
epilepsy: "off",
hivAids: "off",
stroke: "off",
heartDisease: "off",
hbp: "off",
immuneDisorders: "off",
lungDisease: "off",
mentalDisorder: "off",
rheumaticDisease: "off",
smokeTobaccoProducts: "off",
radiationTherapy: "off",
eatingDisorders: "off",
entDisorders: "off",
latex: "off",
localAnasthetics: "off",
metals: "off",
penicillin: "off",
pollen: "off",
foods: "off",
bleedingGums: "off",
bruxism: "off",
halitosis: "off",
ulcer: "off",
dryMouth: "off",
soreJawM: "off",
};
const [patientInfo, setPatientInfo] = useState({
name: "",
surname: "",
gender: "",
dob: "",
});
const [message, setMessage] = useState();
const [medications, setMedications] = useState("");
const [otherInfo, setOtherInfo] = useState("");
const [values, setValues] = useState({});
const getDoH = async (userid) => {
try {
const auth = authHeader();
let config = {
headers: {
"Content-Type": "application/json",
Authorization: auth.Authorization,
},
params: {
userid: userid,
},
};
return await axios.get(API_URL "getdohadmin", config);
} catch (e) {
console.log("Failet to get DoH");
}
};
useEffect(() => {
getDoH(userid).then(
(response) => {
let newValues = switchState;
let valueArray = Object.entries(newValues).map((v, index) => {
v[1] = response.data.switchValues[index];
return v;
});
newValues = Object.fromEntries(valueArray);
setValues({ ...newValues });
newValues = patientInfo;
valueArray = Object.entries(newValues).map((v, index) => {
v[1] = response.data.patientInformation[index];
return v;
});
newValues = Object.fromEntries(valueArray);
setPatientInfo({ ...newValues });
setMedications(response.data.medications);
setOtherInfo(response.data.otherInfo);
},
(error) => {
console.log(error);
}
);
}, []);
const handleChangeMed = (e) => {
setMedications(e.target.value);
};
const handleChangeOtherInfo = (e) => {
setOtherInfo(e.target.value);
};
const handleChangePatientInfo = (e) => {
const { name, value } = e.target;
setPatientInfo({
...patientInfo,
[name]: value,
});
};
const toggle = (name, value) => (e) => {
console.log("Toggle", name, value);
if (value === "off") {
setValues({
...values,
[name]: "on",
});
} else if (value === "on") {
setValues({
...values,
[name]: "off",
});
}
};
const upload = async (event) => {
try {
const auth = authHeader();
let formData = new FormData();
const switchValues = Object.values(values);
const patientInformation = Object.values(patientInfo);
formData.set("patientInformation", patientInformation);
formData.set("switchValues", switchValues);
formData.set("medications", medications);
formData.set("otherInfo", otherInfo);
event.preventDefault();
setMessage("Declaration of health uploaded successfully!");
return await axios.post(API_URL "upload", formData, {
headers: {
"Content-Type": "application/json",
Authorization: auth.Authorization,
},
});
} catch (e) {
setMessage("Declaration of health failed to upload!");
}
};
//If you only want to run the function given to useEffect after the initial render,
//you can give it an empty array as second argument.
return {
toggle,
handleChangeMed,
handleChangeOtherInfo,
upload,
handleChangePatientInfo,
patientInfo,
values,
medications,
otherInfo,
message,
};
};
export default ToggleSwitch;
Теперь в этом коде есть некоторые проблемы, связанные с частью useEffect.
Если я оставлю код таким образом, я получу следующее сообщение в консоли:
Line 134:6: React Hook useEffect has missing dependencies: 'patientInfo', 'switchState', and 'userid'. Either include them or remove the dependency array
также я замечаю в своем API, что эффект использования декларации о здоровье вызывается даже тогда, когда я обновляю другие страницы проекта, не связанные с декларацией о здоровье.
Теперь, если я продолжу и добавлю зависимости, вместо этого я получу вечный цикл, я замечаю, что это приводит к тому, что мой API сходит с ума и продолжает отправлять значения для декларации работоспособности.
Также в консоли я иногда получаю это предупреждение:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
iv потратил часы, читая о useEffect, useinitialState и т. Д. Но я, кажется, не могу найти хорошее решение для этого.
Как я могу изменить этот код, чтобы не возникло утечки памяти или бесконечного цикла ?