I want to adjust a demo provided by some tutorial about React Design Patterns, subject: Higher Order Component, and want to use an external data source from the url: https://jsonplaceholder.typicode.com/users/1 to display the data within my form.
There are two issues I have now when trying to do it:
- How can I use a parameter for the resp. userId? In the tutorial it was just hardcoded within the URL. If I can add a prop like
<UserInfoFormImproved userId={1} />
, how can I access it and put this into the path - if that's the adequate way to do so. - I guess since it's an async call, my Form always displays the "Loading part". What's the best way to solve this issue to ultimately receive the data? I can clearly see
response.data
not being empty when I log it, but the State variables are when I log them inside of theuseEffect Hook
This is what I got so far.
Any help, tips, additional sources to learn this would be highly appreciated.
This is my HOC which I just copied:
import React, { useState, useEffect } from "react";
import axios from "axios";
const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
export const withEditableResource = (Component, resourcePath, resourceName) => {
return (props) => {
const [originalData, setOriginalData] = useState(null);
const [editedData, setEditedData] = useState(null);
useEffect(() => {
(async () => {
const response = await axios.get(resourcePath);
setOriginalData(response.data);
setEditedData(response.data);
})();
}, []);
const onChange = (changes) => {
setEditedData({ ...editedData, ...changes });
};
const onSave = async () => {
const response = await axios.post(resourcePath, {
[resourceName]: editedData,
});
setOriginalData(response.data);
setEditedData(response.data);
};
const onReset = () => {
setEditedData(originalData);
};
const resourceProps = {
[resourceName]: editedData,
[`onChange${capitalize(resourceName)}`]: onChange,
[`onSave${capitalize(resourceName)}`]: onSave,
[`onReset${capitalize(resourceName)}`]: onReset,
};
return <Component {...props} {...resourceProps} />;
};
};
That's my form, I want to use - in the last lines you can find the hard-coded URL path, I want to swap for a parameter:
import { withEditableResource } from "./withEditableResource";
export const UserInfoFormImproved = withEditableResource(
({ user, onChangeUser, onSaveUser, onResetUser }) => {
const { name, email, username } = user || {};
return user ? (
<>
<label>
Name:
<input
value={name}
onChange={(e) => onChangeUser({ name: e.target.value })}
/>
</label>
<label>
Email:
<input
value={email}
onChange={(e) => onChangeUser({ email: e.target.value })}
/>
</label>
<label>
Username:
<input
value={username}
onChange={(e) => onChangeUser({ username: e.target.value })}
/>
</label>
<button onClick={onResetUser}>Reset</button>
<button onClick={onSaveUser}>Save Changes</button>
</>
) : (
<p>Loading...</p>
);
},
`https://jsonplaceholder.typicode.com/users/3`,
"User"
);
And that's the actual use of this two components within my App - I've added my idea on how to solve the parameter argument here:
import { UserInfoFormImproved } from "./HigherOrderComponents/UserInfoFormImproved";
function App() {
return (
<UserInfoFormImproved userId={1} />
);
}
export default App;
Aucun commentaire:
Enregistrer un commentaire