Я провожу эксперимент с React Hooks и столкнулся с проблемой бомбардировки.
Я пытаюсь создать пользовательский крючок состояния формы. Я создал очень упрощенная версия своей работы только для того, чтобы продемонстрировать здесь проблему: https://repl.it/@kadoshms/useCallbackCapture
Сам код находится здесь (для простоты я сохранил весь код в одном основном файле):
import React, { Component, useState, useCallback } from 'react';
import logo from './logo.svg';
import './App.css';
const myHook = (e) => {
const [values, setValues] = useState({
checked: []
});
const setFormValues = useCallback((e) => {
// some logic
if (e.currentTarget.checked) {
setValues({
checked: [...values.checked, e.currentTarget.value]
});
} else {
setValues({
checked: values.checked.filter(v => v !== e.currentTarget.value)
});
}
}, []);
return [values, setFormValues];
}
const checkboxes = Array.from({length: 222}, (v, k) => k+1);
const Checkbox = (props) => (
<input type = "checkbox"
name = {props.name}
value = {props.value}
checked = {props.checked} onChange = {props.onChange} />
);
// Checkbox.whyDidYouRender = true;
const Form = () => {
//
const [formData, setFormData] = myHook();
return (
<form>
{checkboxes.map((c) => <Checkbox name = "foo" checked = {formData['checked'].includes(c.toString())}
key = {`c-${c}`}
onChange = {setFormData} value = {c} />)}
</form>
);
//
};
class App extends Component {
render() {
return (
<div className = "App">
<Form />
</div>
);
}
}
export default App;
Проблема в значительной степени говорит сама за себя в примере, который я привел.
Хук использоватьОбратный звонок, вероятно, фиксирует последнее состояние, из-за которого массив checked не обновляется.
Добавление formData в качестве зависимости или, с другой стороны, удаление мемоизации исправит это.
Хотя это может вызвать проблемы с производительностью, поскольку обработчик по изменению закрывается при каждом рендеринге.
Моя цель — использовать хуки, но сохранить высокую производительность, поэтому каждый флажок должен обновляться только в том случае, если его значение проверил изменено.
Редактировать: Я могу исправить проблему, используя пользовательский обратный вызов React.memo, похожий на shouldComponentUpdate, хотя я думаю, что это менее элегантно.
Это возможно?
Заранее спасибо.





После некоторого дальнейшего чтения я обнаружил следующий раздел часто задаваемых вопросов в официальной документации React: https://reactjs.org/docs/hooks-faq.html#are-hooks-slow-because-of-creating-functions-in-render
ТЛ: ДР: Вместо использования useState я создал редюсер с помощью хука useReducer, как указано в документации.
Если кому-то интересно, буду рад поделиться своим решением конкретной проблемы выше.
Возможный дубликат Предотвращение повторного рендеринга дочерних компонентов из-за использования хуков