Reputation: 566
I have a simple list created using React that displays data using an API.
I'm using axios to fetch and update data.
When updating data of a specific element on the list, every input become empty and only the active input registers to the database.
Example of what it looks like in the database :
Hooks :
const [links, setLinks] = React.useState([]); // List for Links
const [title, setTitle] = React.useState(""); // Title of a link in Links
const [description, setDescription] = React.useState(""); // Description of a link in Links
Function of update :
function handleChangeUpdateLinks(id, event) {
const { name, value } = event.target;
const newLinks = links.map((url) => {
if (url.id === id) {
const updatedUrl = {
...url,
[name]: value,
};
return updatedUrl;
}
return url;
});
setLinks(newLinks);
const info = {
title : value,
description: value,
};
axios
.put("http://localhost:8000/api/link/" + id, info)
.then((res) => {
console.log(res);
console.log("LINKS successfully updated");
})
.catch((error) => {
console.log(error);
});
console.log(newLinks);
}
Onchange
event looped for every input so it can me updated :
onChange={(event) => handleChangeUpdateLinks(url.id,event)}
If I remove the axios function, the returned new array in the console displays correctly the updated inputs.
How can I target the specific input and update it alone without changing the other ones ?
Upvotes: 0
Views: 78
Reputation: 1901
You should put your info object in a State
const [info, setInfo] = useState({ title: "", description: "" });
Updating info
if(name === "title") {
setInfo({(prev) => ({ ...prev, title: value })});
}
if(name === "description") {
setInfo({(prev) => ({ ...prev, description: value })});
}
Upvotes: 1
Reputation: 329
I'd recommend that you create a separate component dedicated only for each input to prevent other inputs from reflecting the value of the current input's value you're mutating. Also, I suggest that you update the data upon form submission since you're updating two attributes with different values.
// Parent component
function ParentComponent() {
const [links, setLinks] = useState([])
function updateCurrentLink(id, name, value) {
setLinks(current => {
const updated = current.map(url => {
if (url.id === id) {
return {
...url,
[name]: value
}
},
return url
})
return updated
})
}
return (
<div>
{links.map(link => (
<Input key={link.id} updateEvent={updateCurrentLink} {...link} />
))}
</div>
)
}
// Input.js
function Input(props) {
const [title, setTitle] = useState(props.title)
const [description, setDescription] = useState(props.description)
function updateTitle(event) {
setTitle(event.target.value)
}
function updateDescription(event) {
setDescription(event.target.value)
}
function submit(event) {
event.preventDefault()
const info = {
title,
description
}
props.updateEvent(props.id, 'title', title)
props.updateEvent(props.id, 'description', description)
axios.put('http://localhost:8000/api/link/' + id, info)
.then(res => {
console.log(res)
})
.catch(error => {
console.log(error)
})
}
return (
<form onSubmit={submit}>
<input type='text' placeholder='Title' value={title} onChange={updateTitle} />
<input type='text' placeholder='Description' value={description} onChange={updateDescription} />
<input type='submit' value='Update' />
</form>
)
}
Upvotes: 1