To introduce myself to React I am developing a small application - it is a 'media bookmark'. For example you really like a chapter from a certain book, so you give the application the name of the book, chapter, that it is a book, a description and a link if applicable.
The error I keep getting is:
Argument of type 'string' is not assignable to parameter of type 'SetStateAction<MediaBookmarkDTO>'
This is my code:
const [newBookmark, setNewBookmark] = useState<MediaBookmarkDTO>({ bookmarkName: '', bookmarkDescription: '', bookmarkType: '', bookmarkChapOrEp: '', bookmarkLink: '' });
And where I try to bind:
<div className="form-group col-md-4">
<label htmlFor="BookmarkName">Name:* </label>
<input type="text" className="form-control" id="BookmarkName" placeholder="Name"
value={newBookmark.bookmarkName} onChange={(e) => setNewBookmark(e.target.value)} />
</div>
CodePudding user response:
Currently you are trying to update newBookmark
with a string. Since a string isn't a MediaBookmarkDTO
, you get an error. You probably meant to update the name only, which you can do inline like this:
<div className="form-group col-md-4">
<label htmlFor="BookmarkName">Name:* </label>
<input
type="text"
className="form-control"
id="BookmarkName"
placeholder="Name"
value={newBookmark.bookmarkName} onChange={(e) => setNewBookmark({
...newBookmark,
bookmarkName: e.target.value,
})}
/>
</div>
CodePudding user response:
First of all welcome to stack overflow family.
newBookmark variable is MediaBookmarkDTO which is a object, when you try to update directly using setNewBookmark(e.target.value), it is trying to provide string value to newBookmark variable, which is where typescript is complaining.
When you are working with forms, in starting I would recommend to have separate state for each field it will help you understand more, when you got the base, then you can use single variable to store all form state. Below is an example to manage the form using a separate state.
import React, { useState } from 'react'
function BookmarkComponent() {
const [bookmarkName, setNewBookmarkName] = useState<string>('');
const [bookmarkDescription, setBookmarkDescription] = useState<string>('');
const [bookmarkType, setBookmarkType] = useState<string>('');
const [bookmarkChapOrEp, setBookmarkChapOrEp] = useState<string>('');
const [bookmarkLink, setBookmarkLink] = useState<string>('');
return (
<form>
<div className="form-group col-md-4">
<label htmlFor="BookmarkName">Name:* </label>
<input type="text" className="form-control" id="BookmarkName" placeholder="Name"
value={bookmarkName} onChange={(e) => setNewBookmarkName(e.target.value)} />
</div>
<div className="form-group col-md-4">
<label htmlFor="BookmarkDescription">Description:* </label>
<input type="text" className="form-control" id="BookmarkDescription" placeholder="Description"
value={bookmarkDescription} onChange={(e) => setBookmarkDescription(e.target.value)} />
</div>
<div className="form-group col-md-4">
<label htmlFor="BookmarkType">Type:* </label>
<input type="text" className="form-control" id="BookmarkType" placeholder="Type"
value={bookmarkType} onChange={(e) => setBookmarkType(e.target.value)} />
</div>
<div className="form-group col-md-4">
<label htmlFor="BookMarkChapter">Chapter:* </label>
<input type="text" className="form-control" id="BookMarkChapter" placeholder="Chapter"
value={bookmarkChapOrEp} onChange={(e) => setBookmarkChapOrEp(e.target.value)} />
</div>
<div className="form-group col-md-4">
<label htmlFor="BookmarkLink">Link:* </label>
<input type="text" className="form-control" id="BookmarkLink" placeholder="Link"
value={bookmarkLink} onChange={(e) => setBookmarkLink(e.target.value)} />
</div>
</form>
)
}
export default BookmarkComponent
When You get more experience you can use Libraries to manage form they are extremely Helpful when managing complex form, below are libraries I used which works very well