Храните массив пользователей и выбранного пользователя в state. Email сделайте кнопкой, а dialog открывайте через showModal после установки выбранных данных; адрес включайте вместе с вложенным geo.
React‑компонент для вывода списка пользователей
Храните массив пользователей и выбранного пользователя в state. Email сделайте кнопкой, а dialog открывайте через showModal после установки выбранных данных; адрес включайте вместе с вложенным geo.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
-
Получить массив пользователей с эндпоинта https://jsonplaceholder.typicode.com/users.
-
Вывести их email‑адреса в виде списка (<ul>).
-
При клике по email открывать модальное окно (<dialog>).
-
Внутри модального окна разместить:
- Заголовок с полным именем пользователя (<header>).
- Секцию с подробной информацией (<section>).
- Кнопку закрытия в нижнем колонтитуле (<footer>).
-
В основной части модального окна отобразить перечень данных пользователя:
- username
- полный адрес (все поля из объекта address).
Ответ
Храните массив пользователей и выбранного пользователя в state. Email сделайте кнопкой, а dialog открывайте через showModal после установки выбранных данных; адрес включайте вместе с вложенным geo.
function Users() {
const [users, setUsers] = React.useState([]);
const [selected, setSelected] = React.useState(null);
const [status, setStatus] = React.useState('loading');
const dialog = React.useRef(null);
React.useEffect(() => {
let active = true; const controller = new AbortController();
(async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users', { signal: controller.signal });
if (!response.ok) throw new Error('HTTP');
const data = await response.json();
if (active) { setUsers(data); setStatus('ready'); }
} catch { if (active) setStatus('error'); }
})();
return () => { active = false; controller.abort(); };
}, []);
React.useEffect(() => { if (selected && !dialog.current.open) dialog.current.showModal(); }, [selected]);
return <>
{status === 'loading' && <p>Загрузка…</p>}
{status === 'error' && <p role="alert">Ошибка загрузки</p>}
<ul>{users.map(user => <li key={user.id}><button onClick={() => setSelected(user)}>{user.email}</button></li>)}</ul>
<dialog ref={dialog} aria-label={selected?.name ?? 'Пользователь'} onClose={() => setSelected(null)}>
{selected && <><header><h2>{selected.name}</h2></header>
<section><p>{selected.email}</p><p>{selected.username}</p><pre>{JSON.stringify(selected.address, null, 2)}</pre></section>
<footer><button onClick={() => dialog.current.close()}>Закрыть</button></footer></>}
</dialog>
</>;
}
Нужен импорт React. Нативный modal dialog поддерживает Escape и управление фокусом. JSON адреса здесь демонстрационно показывает все поля; в готовом интерфейсе их лучше оформить читаемым списком.