Reputation: 5950
I'd like to ask if it is beneficial to model the API response on the client. To be more specific:
First approach:
const [formData, setFormData] = useState(null);
...
useEffect(() => {
const callback = async () => {
try {
const fetchData = await axios.get(...);
setFormData(fetchData.data);
} catch (e) {
...
}
};
callback();
}, []);
return(
<Form>
<Input name="first name" value={formData.firstName}/>
<Input name="last name" value={formData.lastName}/>
</Form>
)
Second approach:
const [formData, setFormData] = useState(new FormModel());
...
useEffect(() => {
const callback = async () => {
try {
const fetchData = await axios.get(...);
setFormData(...formData, fetchData.data);
} catch (e) {
...
}
};
callback();
}, []);
return(
<Form>
<Input name="first name" value={formData.firstName}/>
<Input name="last name" value={formData.lastName}/>
</Form>
)
where FormModel
has already been defined in another file like:
export class FormModel {
firstName: string = undefined;
lastName: string = undefined;
}
Is it the second approach more beneficial and why? Do we need to model the data fetched from the server? Wouldn't it be the same using an interface for formData
in the first approach instead of implementing the second one?
P.S. The second approach might not make big difference from the first one. However, have seen many times that UI creates models for managing data fetched/sent from/to the server and wondering what are the real benefits we get.
Upvotes: 3
Views: 1321
Reputation: 2705
One thing I need to mention, please ignore TypeScript part, because it is just a compiler, with or without TypeScript, it does not matter to my answer and my big picture I will show you.
It seems you're a front-end developer. The quick answer should be: the second approach is my preferred and the way a frontend developer should do. It has some benefits are:
If you are using GraphQL instead of REST, you will never ask this question again because of its strict type of GraphQL. And GraphQL should be the future for API, that should be the way client-side and server-sider communicates. This is a bigger picture for you.
Upvotes: 0
Reputation: 1382
If you know the server responses, you can simple pass the object so you can make a file with all objects that you will need, and you can assign defaults values if you wich, is the more simplest way to replicate the typed as TypeScript, of course you need more things
const formExampleModel = {
firstName: '',
lastName: ''
}
const [formData, setFormData] = useState(formExampleModel);
...
useEffect(() => {
const callback = async () => {
try {
const fetchData = await axios.get(...);
// Here comes the trick, you can choose if you want save the initials value
// or replace all, so you can use
// setFormData(fetchData.data) -> to replace all
// setFormData(prev => ({...prev, fetchData.data})) -> to keep no matches data
setFormData(fetchData.data);
} catch (e) {
...
}
};
callback();
}, []);
return(
<Form>
<Input name="first name" value={formData.firstName}/>
<Input name="last name" value={formData.lastName}/>
</Form>
)
Upvotes: 0
Reputation: 16284
Depends on what you consider beneficial in your business problem.
The second approach will start with a default value, which might be beneficial as an interim display value; and will keep old field values that are not in the response, which might or might not be beneficial in your case. That all.
Unless you use TypeScript, no one will enforce any model rules.
BTW you should modify your code to:
setFormData(prev => ({...prev, fetchData.data}));
Otherwise React will complain about a missing effect dependency.
Upvotes: 1