Хорошо, теперь я вижу это.Единственная опора, которую вы передаете renderBodyCell
, это key
, никаких других опор.Это плохая практика (и просто неправильная).key
s используются как внутренние подсказки по оптимизации для реагирования и не должны использоваться для реквизита.
const renderBodyCell = key => {
const value = contact[key];
const testId = `contact-${key}${
contact.id === 'new-contact' ? '-new-contact' : ''
}`;
const handleChange = e => {
e.preventDefault();
setContact({ ...contact, [key]: e.target.value });
};
return (
<td key={`${key}-${contact.id}`}>
{includes(value, [...groups, ...tendencies]) ? (
<select value={value} data-testid={testId} onChange={handleChange}>
{includes(value, groups)
? map(renderOption, groups)
: map(renderOption, tendencies)}
</select>
) : (
<input value={value} data-testid={testId} onChange={handleChange} />
)}
</td>
);
};
Вместо того, чтобы вводить ключ, вам нужно передать contact
(или контакт иключ, который я предполагаю, но я бы не хотел передавать ключи, как будто они имеют смысл, если только вы не знаете точно, что делаете).
РЕДАКТИРОВАТЬ: Технически, вы были правы, строка не была- рендеринг, потому что ключ не изменился, но это потому, что вы использовали его в качестве опоры, когда вы не должны были.
РЕДАКТИРОВАТЬ # 2: Хорошее время для вас, чтобы изучить, как работает React.Это очень оптимизированная машина.Он не просто перерисовывает компоненты все время, только когда это необходимо.Чтобы выяснить, когда ему нужно перерисовать их, он проверяет реквизиты и состояние (или, в вашем случае, когда вы делаете это функционально, только реквизиты - аргументы функции) и сравнивает их с реквизитами в последний раз, когда компонент былоказаны.Если реквизиты одинаковы (неглубокие равны), то реакция просто говорит, что винт это, мне не нужно обновлять, реквизиты те же.По крайней мере, это поведение для PureComponent
(какие функциональные компоненты).
Поэтому, если вы хотите что-то обновить, убедитесь, что пропускаемые вами реквизиты изменились.