Skip to content

Instantly share code, notes, and snippets.

@shashwata27
Last active January 22, 2024 17:04
Show Gist options
  • Save shashwata27/9bea7e5b688e239ce6a88a2998f81ef1 to your computer and use it in GitHub Desktop.
Save shashwata27/9bea7e5b688e239ce6a88a2998f81ef1 to your computer and use it in GitHub Desktop.
Loaders And Actions: React Router
type TRequestType = "GET" | "POST" | "PUT" | "PATCH";
export const loaderAction = async ({
params,
request,
}: {
params: Object;
request: Request;
}) => {
const data = await request.formData();
const actionType = data.get("actionType");
let teamLink = "";
let requestType: TRequestType = "GET";
let requestData = {};
switch (actionType) {
case "Case_1": {
teamLink = `action-team-link/type/1/team/${params.id}`;
break;
}
case "Case_2": {
teamLink = `action-team-link/type/2/team/${params.id}`;
break;
}
default: {
teamLink = `action-team-link/team/${params.id}`;
requestType = "POST";
requestData = data.get("data-to-post");
}
}
try {
let response: AxiosResponse<EntryResponseType, any>;
requestType = "GET"
? (response = await axios.get(teamLink, {
headers: {
"Content-Type": "application/json",
...otherHeaders,
},
...otherConfig,
}))
: (response = await axios.post<EntryResponseType>(
teamLink,
JSON.stringify(requestData),
{
headers: {
"Content-Type": "application/json",
...otherHeaders,
},
...otherConfig,
}
));
switch (response.status) {
case 200:
return json(
{
data: response.data,
actionType,
...otherReleventData,
},
{
status: 200,
}
);
default:
return json(
{
data: response.data,
actionType,
...otherReleventData,
},
{
status: response.status,
}
);
}
} catch (error: any) {
return json(
{
error: error.response,
actionType,
...otherReleventData,
},
{
status: error.status,
}
);
}
};
import {
json
} from "react-router-dom";
import axios from "axios";
const teamLoader = async ({ params }) => {
try {
const response = await axios.get(`get-team-link/${params.id}`, {
headers: {
"Content-Type": "application/json",
...otherHeaders,
},
...otherConfig,
});
switch (response.status) {
case 200:
return json(
{
data: response.data,
...otherReleventData,
},
{
status: 200,
}
);
case 401:
return json(
{
...otherReleventData,
},
{
status: 401,
}
);
default:
return json(
{
data: response.data,
...otherReleventData,
},
{
status: response.status,
}
);
}
} catch (error) {
return json(
{
response: error.response,
...otherReleventData,
},
{
status: error.status,
}
);
}
};
const router = createBrowserRouter([
{
path: "/",
element: <Root />,
loader: rootLoader,
action: rootAction,
children: [
{
path: "team/:id",
element: <Team />,
loader: teamLoader,
action: teamAction,
},
],
errorElement: <ErrorBoundary />,
},
]);
ReactDOM.createRoot(document.getElementById("root")).render(
<RouterProvider router={router} />
);
import {
Form,
useActionData, useLoaderData, useSubmit
} from "react-router-dom";
const Team = () => {
const submit = useSubmit();
const loaderData = useLoaderData() as ITeamLoaderData;
const { startData, setStartData } = useState({});
const actionData = useActionData() as ITeamActionData;
const { actionOriginated, setActionOriginated } = useState("");
// handle data coming from loader
useEffect(() => {
if (loaderData.status === 200) {
setStartData(loaderData.data);
}
}, [loaderData]);
const handleMimicSubmit = ({ actionType }) => {
submit(
{
actionType: actionType,
},
{
method: "POST",
}
);
};
// handle action data
useEffect(() => {
if (actionData.actionType) {
if (actionData.actionType === "Case_1") {
setActionOriginated("GET originated by submit of form");
} else if (actionData.actionType === "Case_2") {
setActionOriginated("GET by mimicking submit of form");
} else {
setActionOriginated("POST request originated");
}
}
}, [actionData]);
return (
<div>
<h1>Viewing Loader Data</h1>
<p>{startData}</p>
<Form method="post">
<input type="text" name="title" />
<input type="text" name="description" />
<input type="hidden" name="actionType" value="Case_1" />
<button type="submit">Create</button>
</Form>
<button onClick={() => handleMimicSubmit("Case_2")}>
Mimicking POST to do GET
</button>
<button onClick={() => handleMimicSubmit("Case_3")}>
Mimicking POST to do POST
</button>
{actionOriginated}
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment