React Design Patterns~High Order Components/ Data Updating~
Ogasawara Kakeru
Posted on September 26, 2024
・src/server.js
let users = [
{
id: "1",
name: "Smith",
age: 55,
country: "United Kingdom",
magazines: ["VOGUE-UK", "ELLE"],
},
{
id: "2",
name: "Michele",
age: 71,
country: "United States",
magazines: ["VOGUE-US", "ELLE"],
},
{
id: "3",
name: "John",
age: 43,
country: "Canada",
magazines: ["VOGUE-CA", "ELLE"],
},
];
app.get("/users/:id", (req, res) => {
const { id } = req.params;
res.json(users.find((user) => user.id === id));
});
app.post("/users/:id", (req, res) => {
const { id } = req.params;
const { user: editedUser } = req.body;
users = users.map((user) => (user.id === id ? editedUser : user));
res.json(users.find((user) => user.id === id));
});
let SERVER_PORT = 8080;
app.listen(SERVER_PORT, () =>
console.log(`Server is listening on port: ${SERVER_PORT}`)
);
・This file is executed on the server with a command like "node server.js".
・Install Express.js by running a command like "npm install express" if necessary
・If "Server listening on port: 8080" is displayed on the terminal,
means that the server has been successfully connected.
・You can get user by using app.get function.
・You can update user by using app.post function.
・src/components/user-form.jsx
import { includeUpdatableResource } from "./include-updatable-resource";
export const UserInfoForm = includeUpdatableResource(
({ user, onChangeUser, onPostUser, onResetUser }) => {
const { name, age } = user || {};
return user ? (
<>
<label>
Name:
<input
value={name}
onChange={(e) => onChangeUser({ name: e.target.value })}
/>
</label>
<label>
Age:
<input
type="number"
value={age}
onChange={(e) => onChangeUser({ age: Number(e.target.value) })}
/>
</label>
<button onClick={onResetUser}>Reset</button>
<button onClick={onPostUser}>Save</button>
</>
) : (
<h3>Loading...</h3>
);
},
"/users/2",
"user"
);
This component displays name, age as user information.
・include-updatable-resource.jsx
import axios from "axios";
import React, { useEffect, useState } from "react";
const toCapital = (str) => str.charAt(0).toUpperCase() + str.slice(1);
export const includeUpdatableResource = (
Component,
resourceUrl,
resourceName
) => {
return (props) => {
const [initialResource, setInitialResource] = useState(null);
const [resource, setResource] = useState(null);
useEffect(() => {
(async () => {
const response = await axios.get(resourceUrl);
setInitialResource(response.data);
setResource(response.data);
})();
}, []);
const onChange = (updates) => {
setResource({ ...resource, ...updates });
};
const onPost = async () => {
const response = await axios.post(resourceUrl, {
[resourceName]: resource,
});
setInitialResource(response.data);
setResource(response.data);
};
const onReset = () => {
setResource(initialResource);
};
const resourceProps = {
[resourceName]: resource,
[`onChange${toCapital(resourceName)}`]: onChange,
[`onPost${toCapital(resourceName)}`]: onPost,
[`onReset${toCapital(resourceName)}`]: onReset,
};
return <Component {...props} {...resourceProps} />;
};
};
・This component is a High Order Component.
・This component retrieves user information with axios on the server.
・This component updates user information with axios on the server.
・This component returns a component received as props, passing some props and user , onChangeUser, onPostUser, onResetUser as user props.
・src/App.js
import { UserInfoForm } from "./components/user-form";
function App() {
return (
<>
<UserInfoForm />
</>
);
}
export default App;
・This component returns the UserInfoForm component .
Posted on September 26, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.