#reactjs #react-hooks #react-functional-component
#reactjs #реагирующие хуки #реагирующий функциональный компонент
Вопрос:
Я использую реагирующие хуки и функциональные компоненты. В моем функциональном компоненте происходят некоторые странные вещи, из которых я не могу найти выход. В useEffect изначально у меня не было возвращаемого массива, чтобы предотвратить бесконечный цикл, и я пытался использовать rowData в deleteClickedHandler, но он всегда пуст. После некоторого исследования выяснилось, что способ обойти это — использовать useRef , который, казалось, сработал, но вызвал гнев ESLinter, который потребовал, чтобы rowData был в массиве, который вызывает повторный рендеринг для useEffect . Это приводит к тому, что обработчик deleteClickedHandler получает данные из rowDataRef.current, но вызывает бесконечный цикл.
Обработчик deleteClickedHandler выполняет оптимистичный параллелизм, изменяет состояние rowData и взаимодействует с api.
Через несколько часов я не знаю, как это исправить.
Если я удаляю rowData из массива, который сообщает useEffect, когда нужно выполнить повторную визуализацию, обработчик удаления работает, но не выполняет повторную визуализацию, и поскольку deleteClickedHandler является обработчиком, я не могу определить, как вызвать повторную визуализацию без бесконечного цикла.
Я уверен, что делаю что-то глупое, но не могу определить, почему rowData недоступен в deleteClickedHandler — я знаю, что обработчик является формой замыкания, но rowData — это состояние.
const initialState = {
id: 0,
credit: false,
transactionAmount: 0,
accountBalance: 0,
transactionDate: new Date(),
confirmation: "",
comment: "",
action: "EDIT",
};
const SERVER_URL='/api/checking'; //process.env.REACT_APP_SERVER_URL;
function Checking() {
const [rowData, setRowData] = useState([]);
const [newData, setNewData] = useState(initialState);
const [displayModal, setModalDisplay] = useState(false);
const columnDefinitions = Columns();
const rowDataRef = useRef(rowData);
useEffect(() => {
fetch(SERVER_URL)
.then((response) => response.json())
.then((rowData) => setRowData(rowData));
rowDataRef.current = rowData;
}, [rowData]);
function deleteClickedHandler(props) {
let fetchUrl = SERVER_URL "/" props.id;
let balance = 0.0;
let transactionAmount = 0.0;
let data = rowDataRef.current;
if (
data.length > 0 amp;amp;
window.confirm("Are you sure you wish to delete transaction: " props.id)
) {
for (let i = 0; i < data.length; i ) {
transactionAmount = props.credit
? props.transactionAmount
: -1.0 * props.transactionAmount;
balance = balance transactionAmount;
if (data[i].id === props.id) {
data.splice(i, 1);
}
if (data[i].id > props.id) {
data[i].accountBalance = balance;
}
}
setRowData(data);
CustomFetch(fetchUrl, "DELETE");
}
}
function rowActionHandler(props) {
switch (props.action) {
case "DELETE":
deleteClickedHandler(props);
break;
default:
break;
}
}
const context = { componentParent: rowActionHandler };
Правка 1
Следующее очищает бесконечный рендеринг и позволяет удалению получить доступ к rowData через rowDataRef, но не выполняет повторный рендеринг после удаления. Как мне заставить повторный рендеринг при удалении работать?
useEffect(() => {
fetch(SERVER_URL)
.then((response) => response.json())
.then((rowData) => {
setRowData(rowData)
rowDataRef.current = rowData;
});
}, []);
Комментарии:
1. когда именно вы хотите
useEffect
запустить? Из того, что я вижу, сам эффект будет вызывать бесконечный повторный рендеринг запрос, помимо того, что вы описали выше.2. Я хочу, чтобы он запускался при загрузке и при изменении rowData
Ответ №1:
Хотя это не идеально, есть обходной путь, который является тем же, что я делал вручную. Это делается для принудительной перезагрузки страницы с помощью приведенного ниже оператора. Если есть кто-то, кто может обеспечить государственный подход, я готов изменить этот ответ.
window.location.reload();