Динамический массив внутри компонента
Всем привет!
Есть задачка, реализовать компонент для создания новой статьи в блоге.
В самой блоке редактирования есть поле тег.

После нажатия на Add Tag, ниже должен появится такой же input и кнопка.
На сервер теги отправляются массивом. Мой подход следующий, есть стейт:
const [tags, setTags] = useState(['']); который я хочу заполнять значениями(tag).
Далее идет ф-ия:
const createTags = () => {
return tags.map((tag, i) => (
<div className={style.tag} key={i}>
<label className={style.label}>
<input
type="text"
placeholder="Tag"
className={style.tagInput}
{...register(`tagList.${i}`)}
/>
{tags.length > 1 ? (
<button type="button" className={style.btnDelete} onClick={() => deleteTag()}>
Delete
</button>
) : null}
<button type="button" className={style.btnAdd} onClick={(e) => addTag(e, i)}>
Add tag
</button>
</label>
</div>
));
};
Из-за того, что по дефолту в массиве есть элемент, то индекс тегов смещается и первым эл-ом является пустая строка. Если в состоянии убрать строку, то в моем случае поле инпут и button не появится. Возможно нужно изменить подход, но этот же компонент я бы хотел использовать при редактировании статьи, т.е. что бы в инпутах лежали данные из сервера, в случае если я редактирую. Буду рад помощи!
Ответы (1 шт):
Обычно с тегами делают нечто такое... Стилей в примере нет, но думаю что идея будет понятна.
Теги добавляются в список. Из списка теги можно удалять, нажимая на крестик...
//
function App() {
const [tag, setTag] = React.useState([])
return <section>
<Add add={setTag} />
<List tag={tag} act={setTag} />
<div>
<button>Send</button>
</div>
</section>
}
//
function List({tag, act}) {
return <ul>
{tag.map(o => <Item key={o.id} data={o} act={act} />)}
</ul>
}
//
function Item({data, act}) {
const del = _ => act(a => a.filter(o => o.id != data.id))
return <li>
{data.val}
<span onClick={del}> x</span>
</li>
}
//
function Add({add}) {
const [val, setVal] = React.useState([])
const act = _ => add(a => {
const o = {
id: new Date(),
val
}
setVal('')
return [...a, o]
})
return <div>
<input value={val} onChange={e => setVal(e.target.value)} />
<button onClick={act}>Add</button>
</div>
}
const domContainer = document.querySelector('#like_button_container');
const root = ReactDOM.createRoot(domContainer);
root.render(<App />);
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<div id="like_button_container"></div>