Я проводил эксперимент с 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;
Проблема в значительной степени очевидна в приведенном мною примере.Хук useCallback , вероятно, захватывает последнее состояние, из-за которого массив checked
не обновляется.Добавление formData
в качестве зависимости или, с другой стороны, удаление памятки исправит это.Хотя это может вызвать проблемы с производительностью, поскольку обработчик onChange закрывается при каждом рендеринге.
Моя цель - использовать хуки, но сохранять высокую производительность, поэтому каждый флажок должен обновляться, только если он проверено значение изменено.
Редактировать: Я могу исправить проблему с помощью пользовательского обратного вызова React.memo, похожего на shouldComponentUpdate, хотя я думаю, что он менее элегантен.
Возможно ли это?
Заранее спасибо.