AlyaKra
AlyaKra

Reputation: 566

React: Changing value of separate inputs

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 : enter image description here

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

Answers (2)

Abu Dujana Mahalail
Abu Dujana Mahalail

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

jstarnate
jstarnate

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

Related Questions