I attempted to use the react-router
action
and Form
components, but it appears that the action
function is not being invoked, and no errors are showing in the console. I have already implemented the Data
router, exported the action
function, and included it in the Router. Any insights on why the action
function might not be triggering?
I've been following the React Router documentation, and my main concern is the absence of errors or warnings for debugging purposes.
Login component:
import React from 'react';
import { Form } from 'react-router-dom';
export async function action({ request }) {
console.log(request);
const data = await request.formData();
const formSubmission = {
email: data.get('email'),
password: data.get('password'),
};
console.log(formSubmission);
}
const AdminLogin = () => {
return (
<div>
<Form>
<input
type="text"
placeholder="Enter email or User ID"
name="email"
autoComplete="username"
/>
<input
type="password"
placeholder="Enter Password"
name="password"
autoComplete="current-password"
/>
<button>Log In</button>
</Form>
</div>
);
};
export default AdminLogin;
Router component:
import {
Route,
createBrowserRouter,
createRoutesFromElements,
RouterProvider,
redirect
} from "react-router-dom";
import { Home, MainNav } from './Assets/User components/UserImports';
import './Assets/User components/StyledComponents/style.css';
import LogIn, { action as userAction } from "./Assets/User components/LogIn";
import Dashboard from "./Assets/Admin components/Dashboard";
import AdminLayout from "./Assets/Admin components/AdminLayout";
import EditDeals from "./Assets/Admin components/EditDeals";
import { loader } from "./Assets/User components/Deals";
import AdminLogin, { action } from "./Assets/Admin components/AdminLogin";
function App() {
const takeRouter = createBrowserRouter(createRoutesFromElements(
<>
<Route path="*" element={<code>404 Not Found</code>} />
<Route path="/" element={<MainNav />}>
<Route path="adminlogin" action={action} element={<AdminLogin />} />
<Route index element={<Home />} loader={loader} errorElement={<h1>Oh! there was an error!</h1>} />
<Route path="login" action={userAction} element={<LogIn />} />
</Route>
<Route path="admin" element={<AdminLayout />} loader={async () => {
const loggedIn = false;
return loggedIn === false ? redirect('/adminlogin') : null;
}}>
<Route index element={<Dashboard />} />
<Route path="editdeals" element={<EditDeals />} />
</Route>
</>
));
return (
<>
<div className="app">
<RouterProvider router={takeRouter} />
</div>
</>
);
}
export default App;
By default, the Form
component uses GET submissions, which don't trigger route actions.
See GET submissions:
The default method is "get". Get submissions will not call an action. Get submissions are the same as a normal navigation (user clicks a link) except the user gets to supply the search params that go to the URL from the form.
Specify a method
to the form, anything other than "get"
should trigger the route action.
This determines the HTTP verb to be used. The same as plain HTML form method, except it also supports "put", "patch", and "delete" in addition to "get" and "post". The default is "get".
Also, you should be explicit with the button
element's type
attribute even though type="submit"
is the default when unspecified.
Example:
const AdminLogin = () => {
return (
<div>
<Form method="post"> // <-- specify non-"get" method
<input
type="text"
placeholder="Enter email or User ID"
name="email"
autoComplete="username"
/>
<input
type="password"
placeholder="Enter Password"
name="password"
autoComplete="current-password"
/>
<button type="submit"> // <-- explicit button type
Log In
</button>
</Form>
</div>
);
};