Сделайте checkbox управляемым, обновляйте состояние функционально и используйте отдельный идентификатор для каждой группы. Очистка dblclick уже реализована верно.
Проведение ревью и отладка React‑компонентов
Сделайте checkbox управляемым, обновляйте состояние функционально и используйте отдельный идентификатор для каждой группы. Очистка dblclick уже реализована верно.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В этом задании требуется выполнить обзор кода и исправить найденные недочёты по своему усмотрению.
const ListItem = (itemProps) => {
const { label, handleToggle } = itemProps;
return (
<li><input type="checkbox" onChange={handleToggle} name={label} />{label}</li>
);
};
export default function List() {
const [checkedItems, setCheckedItems] = useState([]);
useEffect(() => {
const onDblClick = () => console.log('dblclicked');
document.addEventListener('dblclick', onDblClick);
return () => document.removeEventListener('dblclick', onDblClick);
}, []);
const toggleItem = (e) => {
const itemName = e.target.name;
if (checkedItems.includes(itemName)) {
setCheckedItems(checkedItems.filter(el => el !== itemName));
} else {
setCheckedItems([...checkedItems, itemName]);
}
};
const cities = [
{ name: 'Moscow' },
{ name: 'St. Petersburg' },
{ name: 'London' },
];
const carBrands = [
{ name: 'Toyota' },
{ name: 'Haval' },
{ name: 'Nissan' },
];
return (
<div>
<ul>Посещённые вами города: {cities.map(el => <ListItem key={el.name} handleToggle={toggleItem} label={el.name} />)}</ul>
<ul>Желаемые вами марки автомобилей: {carBrands.map(el => <ListItem key={el.name} handleToggle={toggleItem} label={el.name} />)}</ul>
</div>
);
}
Ответ
Сделайте checkbox управляемым, обновляйте состояние функционально и используйте отдельный идентификатор для каждой группы. Очистка dblclick уже реализована верно.
Добавьте импорт useState, useEffect. Вынесите заголовки из ul, а текст checkbox поместите в label. Вместо имени как общего ключа используйте, например, city:Moscow и car:Toyota.
const ListItem = ({ id, label, checked, onToggle }) => (
<li><label><input type="checkbox" checked={checked}
onChange={() => onToggle(id)} />{label}</label></li>
);
// Внутри List:
const toggleItem = id => setCheckedItems(previous =>
previous.includes(id) ? previous.filter(item => item !== id) : [...previous, id]
);
const renderGroup = (items, group) => <ul>{items.map(({ name }) => {
const id = `${group}:${name}`;
return <ListItem key={id} id={id} label={name}
checked={checkedItems.includes(id)} onToggle={toggleItem} />;
})}</ul>;
// В JSX: <h2>Посещённые города</h2>{renderGroup(cities, 'city')}
// <h2>Марки автомобилей</h2>{renderGroup(carBrands, 'car')}
Для изменяемого каталога лучше реальные ID. Перенос постоянных массивов за компонент допустим, но не исправляет функциональный баг сам по себе.