Skip to content
Advertisement

Update one element of State React

I have a problem, a bit hard to explain.

I use Hooks to set a state, from the data I receive from my API. I display it on my frontend, no problem.

I would like to update ONE value, from ONE element.

Here is my full component :

import { UidContext } from "../components/AppContext"
import { totalIncome, totalFees, balance } from "./balance.utils"
import React, { useContext, useEffect, useState } from "react"
import axios from "axios"

export default function Balance() {
    const uid = useContext(UidContext)
    const [userWalletIncomes, setUserWalletIncomes] = useState('')
    const [userWalletFees, setUserWalletFees] = useState('')
    const [formIncomes, setformIncomes] = useState(false)

    useEffect(() => {
        if (uid !== null) {
            axios.get(`${process.env.REACT_APP_API_URL}api/balance/${uid}`)
                .then((res) => {
                    setUserWalletIncomes(res.data[0].incomes)
                    setUserWalletFees(res.data[0].fees)
                })
        }
    }, [uid])

    return (
        <div className="h-screen">
            <section className="border my-2 w-max md:w-11/12 mx-auto text-center">
                <h1 className="text-3xl my-5">Revenus</h1>

                {formIncomes === false && (
                    Object.entries(userWalletIncomes).map(([key, value]) => {
                        return (
                            <div className="text-left mx-auto flex" key={key}>
                                <p className="w-32 border p-1 capitalize">{key} :</p>
                                <p onClick={(e) => setformIncomes(true)} className="w-32 border p-1 text-green-500">{value}€</p>
                            </div>
                        )
                    })
                )}
                {formIncomes === true && (
                    Object.entries(userWalletIncomes).map(([key, value]) => {
                        return (
                            <div className="text-left mx-auto flex" key={key}>
                                <p className="w-32 border p-1">{key} :</p>
                                <input className="w-32 border p-1 text-green-500"
                                    value={value}
                                    onChange={(e) => setUserWalletIncomes(value)} />
                            </div>
                        )
                    })
                )}
            </section>
        </div>
    )
}

So, when I click on my <p>, it transforms to an input. Then I would like to modify the amount of income, and set it to the state.

For information, my collection (mongo) look like this :

{
    "_id": {
        "$oid": "60c763df3d260204865d2069"
    },
    "incomes": {
        "salaire1": 1130,
        "salaire2": 640,
        "Prime": 90
    },
    "__v": 0,
    "fees": {
        "Box": 35,
    }
}

So I need to update only the income category, and only the amount from the key selected. I don’t know if I’m clear…

Any idea ?

Additional info : My setUserWalletIncomes in the input erase all the state, and replace it with the only value from the input.

Advertisement

Answer

You can take advantage of object destructuring to do that

setUserWalletIncomes({...userWalletIncomes, incomes: {...userWalletIncomes.incomes, [keySelected]: value}});

See the MDN docs for more info on the matter.

Edit: You already have it thanks to your Object.entries func. See below for full code.

<input className="w-32 border p-1 text-green-500"
                                    value={value}
                                    onChange={(e) => setUserWalletIncomes({...userWalletIncomes, incomes: {...userWalletIncomes.incomes, [key]: e.target.value}})} />
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement