Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

bearbytestudio's avatar

How do I set form data, and then immediately submit? Getting stale data sent to controller.

Hi everyone! Using React / Inertia / Laravel, I'm having a hard time updating form data using setData, then immediately making an AJAX request with the updated data. The data becomes stale. Here is the code, the "due" field being submitted is stale:

const {data, setData, put} = useForm({
    "due": "",
});

const updateDate = (d) => {
    setData("due", new Date(d).toLocaleDateString("en-US"));
    setTimeout(() => {
        put(`/${project.client.short_name}/${project.job_code}`);
    }, 0);
};

As above, I tried using a setTimeout to make the update happen on the next tick, but that doesn't work. Logging "due" on server side, it is showing the stale data.

0 likes
4 replies
LaryAI's avatar
Level 58

The issue is that the put request is being sent before the setData function has a chance to update the state. One solution is to use the useEffect hook to watch for changes to the due field and then send the put request. Here's an example:

import { useForm } from '@inertiajs/inertia-react';

const MyComponent = () => {
  const { data, setData, put } = useForm({
    due: '',
  });

  useEffect(() => {
    put(`/${project.client.short_name}/${project.job_code}`);
  }, [data.due]);

  const updateDate = (d) => {
    setData('due', new Date(d).toLocaleDateString('en-US'));
  };

  return (
    <form onSubmit={put}>
      <input type="text" value={data.due} onChange={(e) => setData('due', e.target.value)} />
      <button type="submit">Submit</button>
    </form>
  );
};

In this example, the useEffect hook watches for changes to the due field and sends the put request when it detects a change. The updateDate function simply updates the due field using setData. The form itself is submitted using the put function provided by useForm.

2 likes
Hassankhan's avatar

I am using inertia react and Laravel i want to update data in my dom after submission form

import React, { useEffect, useState } from 'react'
import Modal from '../BootstrapComponents/Modal';
import { usePage } from '@inertiajs/react'
const mainDivStyle = {

    height: "100vh",
    textAlign: "center"
}

const tableStyle = {
    width: "100%",
    border: "2px solid black",
}
function Users({ users }) {

    const [values, setValues] = useState();
    useEffect(() => {
        setValues(users)
    }, [users])
    return (
        <>
            <Modal />
            <div style={mainDivStyle}>
                <div>
                    <h1>
                        Login
                    </h1>
                </div>
                <button type="button" className="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
                    Launch demo modal
                </button>
                <div>
                    <table style={tableStyle}>
                        <thead>
                            <tr>
                                <th>Id</th>
                                <th>Name</th>
                                <th>Email</th>
                                <th>Action</th>
                            </tr>
                        </thead>
                        <tbody>
                            {users.map((item, i) => {

                                return (
                                    <tr key={i}>
                                        <td>{item.id}</td>
                                        <td>{item.name}</td>
                                        <td>{item.email}</td>
                                        <td>
                                            <div>
                                                <button type='button'>Edit</button>
                                                <button type='button'>Delete</button>
                                            </div>
                                        </td>

                                    </tr>
                                )

                            })}
                        </tbody>
                    </table>
                </div>
            </div>
        </>
    )
}

export default Users

import React from 'react' import { useState } from 'react' import { router } from '@inertiajs/react' import { useNavigate } from 'react-router-dom'

function Modal() {

const [values, setValues] = useState({
    name: "",
    email: "",
})
function handleChange(e) {
    const key = e.target.id;
    const value = e.target.value
    setValues(values => ({
        ...values,
        [key]: value,
    }))
}

function handleSubmit(e) {
    e.preventDefault();
    router.post('/user-store', values)
}
function getUsers() {

}
return (
    <>
        <div className="modal fade" id="exampleModal" tabIndex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
            <div className="modal-dialog">
                <div className="modal-content">
                    <div className="modal-header">
                        <h1 className="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
                        <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div className="modal-body">
                        <form onSubmit={handleSubmit}>
                            <div className="form-group mb-2">
                                <label htmlFor="">Name</label>
                                <input type="text" name='name' id='name' className='form-control' placeholder='Enter Name' value={values.name} onChange={handleChange} />
                            </div>
                            <div className="form-group">
                                <label htmlFor="">Email</label>
                                <input type="text" name='email' id='email' className='form-control' placeholder='Enter Email' value={values.email} onChange={handleChange} />
                            </div>
                            <div className="modal-footer">
                                <button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                                <button type="submit" onClick={getUsers} className="btn btn-primary">Save changes</button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </>

)

}

export default Modal

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Inertia\Inertia;

class UserController extends Controller
{
    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function index()
    {
        $users = $this->user->latest()->get();
        return Inertia::render('Auth/Users', [
            'users' => $users
        ]);
    }

    public function store(Request $request)
    {
        $user = $this->user->create([
            'name' =>  $request->name,
            'email' =>  $request->email,
            'password' => Hash::make($request->name),
        ]);
        return $user;
    }
}
noxioustoo's avatar

You can set form data and then immediately submit like that:

const updateDate = (d) => {
	data.due = new Date(d).toLocaleDateString("en-US");
    put(`/${project.client.short_name}/${project.job_code}`);
};

data is initially an empty object. So you don't have to pass any initial object like in your code, if you don't want to.

Please or to participate in this conversation.