how to return values from a Laravel Sever to React with inertiajs?

Viewed 485

I'm am trying to get a message to show after a post in React from a Laraval server using InertiaJS.

From what I can find in docs / online / in other (semi) related questions the following is an isolated version of what I think should work - I'm under the impression it should be added to my props. My Test component does reload so the redirect is working just with no message and props remaining undefined - What am I not understanding?

Laravel Controller:

use Illuminate\Support\Facades\Redirect;
use Inertia\Inertia;
use Illuminate\Routing\Controller as BaseController;

class TestController extends BaseController
{
    function test(){
       return Inertia::render('Test');
    }

    function testResponse(){
        //dd("I GET TO HERE, SO ITS NOT A ROUTING ISSUE!")
        return Redirect::back()->with('message', 'Test message from server.');
    }
}

My React Test Component

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

const Test = (props) => {

    const [serverMessage, setServerMessage] = useState('no message');



  return <div>
      <div>{serverMessage}</div>
      <Link className="hover:bg-blue-700 bg-blue-400 text-white py-1 px-3 rounded" href={route('testResponse')} method="post" as="button">
          Get Server Response
      </Link>
  </div>;
};

export default Test;
1 Answers

It is because the flash message is not passed to the react component. To do that, you need to modify the HandleInertiaRequest.php to add a props for flash message that is globally accessible. That means the props is for all the pages.

public function share(Request $request)
{
    return array_merge(parent::share($request), [
        'auth' => [
            'user' => $request->user(),
        ],
        'flash' => [
            'message' => fn () => $request->session()->get('message'),
        ],
    ]);
}

Then, in /resource/js/pages/Test.jsx, you will have the following code

import { Link } from '@inertiajs/inertia-react'
import React, { useEffect, useState } from 'react'

const Test = (props) => {
    const [serverMessage, setServerMessage] = useState('no message')

    console.log('Test.jsx props: ', props)

    useEffect(() => {
        const {
            flash: { message = '' },
        } = props
        if (message) {
            setServerMessage(message)
        }
    }, [props.flash.message])

    return (
        <div>
            <div>{serverMessage}</div>
            <Link
                className='hover:bg-blue-700 bg-blue-400 text-white py-1 px-3 rounded'
                href={route('testResponse')}
                method='post'
                as='button'
            >
                Get Server Response
            </Link>
        </div>
    )
}

export default Test

Btw you're missing the useState import at the top.

And then in web.php you should define the routes like this:

use App\Http\Controllers\TestController;

Route::get('/test', [TestController::class, 'test'])->name('test');
Route::post('/testResponse', [TestController::class, 'testResponse'])->name('testResponse');

Actually this is documented in the inertia js. Check out https://inertiajs.com/shared-data

Related