Official Solution
import React, { useMemo, useState } from 'react';
function uid() {
return Date.now().toString(36) + Math.random().toString(36).slice(2);
}
export default function App() {
const [skills, setSkills] = useState([{ id: uid(), value: 'React' }]);
const [submitted, setSubmitted] = useState(false);
const error = useMemo(() => {
if (!submitted) return '';
const bad = skills.some((s) => !s.value.trim());
return bad ? 'Remove empty skills or fill them.' : '';
}, [submitted, skills]);
function add() {
setSkills((prev) => [...prev, { id: uid(), value: '' }]);
}
function remove(id) {
setSkills((prev) => prev.filter((s) => s.id !== id));
}
function update(id, value) {
setSkills((prev) => prev.map((s) => s.id === id ? { ...s, value } : s));
}
function submit(e) {
e.preventDefault();
setSubmitted(true);
if (skills.some((s) => !s.value.trim())) return;
alert('Saved skills on meetcode: ' + skills.map((s) => s.value.trim()).join(', '));
}
return (
<div style={{ padding: 16, width: 560 }}>
<h2 style={{ marginTop: 0 }}>Skills</h2>
<form onSubmit={submit} style={{ display: 'grid', gap: 10 }}>
{skills.map((s, idx) => (
<div key={s.id} style={{ display: 'flex', gap: 10 }}>
<input value={s.value} onChange={(e) => update(s.id, e.target.value)} placeholder={'Skill ' + (idx + 1)} style={{ flex: 1, padding: '10px 12px', borderRadius: 12, border: '1px solid #bbb' }} />
<button type='button' onClick={() => remove(s.id)} disabled={skills.length === 1} style={{ padding: '10px 12px', borderRadius: 12, border: '1px solid #ddd', background: '#fff', opacity: skills.length === 1 ? 0.6 : 1 }}>Remove</button>
</div>
))}
{error ? <div style={{ color: '#c1121f' }}>{error}</div> : null}
<div style={{ display: 'flex', gap: 10 }}>
<button type='button' onClick={add} style={{ padding: '10px 14px', borderRadius: 12, border: '1px solid #ddd', background: '#fff' }}>Add field</button>
<button type='submit' style={{ padding: '10px 14px', borderRadius: 12, border: 0, background: '#0b5', color: '#fff' }}>Save</button>
</div>
</form>
</div>
);
}
No comments yet. Start the discussion!