react hook for submit button not changing data

Viewed 37

Form.jsx

...

const initialValues = {
    name: '',
    id: '',
    price: ''
}

const initialSD = {
    name: "Test Name",
    id: "Test ID",
    price: "Test Price"
}


const Form = () => {

const{
        values,
        setValues,
        handleInputChange
    }=useForm(initialValues);

const {
        sd,
        setSD,
        handleSubmit
    }=UseButton(initialSD);

    return(
        <EasybaseProvider ebconfig={ebconfig}>
            <React.Fragment>
                <div className="form-wrapper">
                    <form className={classes.root} autoComplete="off" onSubmit={handleSubmit(values)}>

...

UseButton.jsx

import React, { useState } from 'react'

export default function useButton(incomingSD) {

    const [sd, setSD] = useState(incomingSD);

    const handleSubmit = values => e => {
       
        e.preventDefault()
        console.log('1', sd); // gives current values
        console.log('2', values); // gives new values to be added
        setSD({
            'name': values.name,
            'id': values.id,
            'price': values.price
        }) // expecting this to set "sd" values to the new "values" values.
        console.log('3', sd); // logs the same old "sd" values and the content on the pages doesn't change to reflect the new values
      }


    return {
        sd,
        setSD,
        handleSubmit
    }
}

setSD in UseButton.jsx isn't changing the values stored in sd as I'm expecting it to, and as a result the page isn't updated with the new data.

I'm trying to understand why this is the case. At this stage it seems like the setSD setter is not immediately modifying sd, but I'm not sure why that's the case.

If I was using something like sd = {name: 'new name', id: 'new id', price: 'new price'} it would be immediately taking effect and the data on the page would change as a result.

I'm somewhat new to working with react state and trying to get a better understanding of the way this is working to create this issue.

1 Answers

setState are asynchronous. React will schedule update once event handler finishes (because this way react can update component once if there are many setStates). Here is more in depth explanation why react work this way https://github.com/facebook/react/issues/11527#issuecomment-360199710

In your case you can declare updated object before setState and use it after

const updatedSD = {
   'name': values.name,
   'id': values.id,
   'price': values.price
};
setSD(updatedSD);
console.log(updatedSD)
Related