Я хочу получить динамически построенную форму с контролируемыми компонентами, которые хорошо масштабируются. Проблема, с которой я сталкиваюсь, заключается в том, что при обновлении состояния происходит повторная визуализация всей формы (или что-то дорогое), что вызывает отставание эпического типа.
// Generate some example fields
let defaultFields = {};
for(let n=0; n<1000; n++){
defaultFields[n.toString()] = {'id':n.toString(), 'value':'','label':'Field '+n}
}
const [valuesById, setValuesById] = useState(defaultFields);
const updateValueCallback = React.useCallback((e)=>{
e.preventDefault();
e.persist();
setValuesById(prevValuesById => {
let fieldId = e.target.id;
return {...prevValuesById,
[fieldId]:{
'id':fieldId,
'value':e.target.value,
'label':'Field '+fieldId
}};
});
});
return <div>
{ Object.entries(valuesById).map(([id,formField]) => {
return <p key={formField.id}>
<label>{formField.label}
<SingleLineStringInput isRequired={false} value={formField.value} onChangeCallback={updateValueCallback} id={formField.id} name={'name_'+formField.id} />
</label>
</p>
})
}
</div>;
Если реквизиты не меняются для 999 изполя, то почему они перерисовывают? Или что на самом деле происходит здесь (поля на самом деле не мигают в инструменте отладки, а родительские)? Мне действительно нужна помощь, чтобы лучше понять это, и исправление, которое не слишком сильно отличается от того, что я сделал, поскольку мы построили большое количество логики поверх этой базовой структуры и только сейчас поняли, что это не масштабирование.
SingleLineInput:
const SingleLineStringInput = React.memo(({name, id, value, onChangeCallback}) => {
console.log("UPDATING "+id);
return <input className={'input ' + inputClasses.join(' ')} name={name} id={id} type="text"
value={(value === null) ? '' : value}
onChange={onChangeCallback} />
});