Alfonso Rodriguez's avatar

If you meant to render a collection of children, use an array instead

I have a Layout where I want to use a notification component, but when returning the properties that make the notification component display when doing a redirect()->route(), when trying to render the view, it returns the error

"Uncaught (in promise) Error: Objects are not valid as a React child (found: object with keys {type, code}). If you meant to render a collection of children, use an array instead."

When executing the store or the update and everything goes well, something like this returns...

return redirect()->route(route)
             ->with('success', [
                 'type' => 'success',
                 'code' => trans('success-create')
             ]);

inertia's share flash looks something like this...

'flash' => [
                 'success' => fn() => $request->session()->get('success'),
                 'error' => fn() => $request->session()->get('error'),
                 'alert' => fn() => $request->session()->get('alert'),
             ]

And the component I use it this way...

const { flash }: any = usePage().props
const _notification = Object.keys(flash).map((_m: string) => {
        return (flash[_m] != null ? (<Notification type={flash[_m].type} code={flash[_m].code} />)  :  <></>)
    })

 return ( <>{flash && flash.success || flash.error || flash.alert && (<>{_notification}</>) } </>
0 likes
2 replies
aidil's avatar

The error message "Uncaught (in promise) Error: Objects are not valid as a React child" is occurring because the value passed to the flash.success prop is an object instead of an array or a string. React expects children elements to be an array or a string, but in this case, it is receiving an object with properties type and code.

It looks like the flash object is being populated in the Inertia middleware with data from the session. It appears that when you're redirecting with a flash message, you're passing an object with type and code properties rather than an array or a string. This causes the error when it tries to render the flash.success prop.

In order to fix this issue, you should change the flash data in your controller function to be an array or a string instead of an object. You could return the flash data like this:

return redirect()->route(route)
             ->with('success', 'success-create');

Or like this:

return redirect()->route(route)
             ->with('success', ['type' => 'success', 'code' => trans('success-create')]);

by making these changes, the error message you encountered should be resolved. The flash.success prop will now be an array or a string and will be compatible with React's expected children types. Additionally, the _notification component should be able to properly map through the flash object and create the correct number of Notification components with the correct type and code props.

It's worth noting that the check and the short-circuiting logical operator in the return statement :

return ( <>{flash && flash.success || flash.error || flash.alert && (<>{_notification}</>) } </>

It's not necessary, if you pass array instead of object, the filter to check whether flash is null or not will be handled implicitly by javascript.

It's also worth noting that if you are using Inertia, you may have to make sure that you are passing the flash data to your views in the right way, or that the way you're passing flash data in the controller matches the way you're using it in your Inertia views. Make sure that you're consistent and passing the data in a way that is compatible with both React and Inertia.

1 like
Alfonso Rodriguez's avatar

@aidil Hey thanks for the answer! I was reviewing and the change I made to achieve the functionality was in the validation for the component, so the change was this:

return ({!Object.values(flash).every(f => f === null) &&
                (<>{_notification}</>)
            })

Thank you very much for the help!!

Please or to participate in this conversation.