To read more articles like this, visit my blog
Every modern ReactJS application deals with data in some way. We are fetching data and letting people interact with it throughout the whole application.
But if we are not careful about what data is coming into our website it can cause our application to fail.
One of the major reasons an application crashes on runtime is bad data.
Today we will see one way to sanitize data in React applications.
The problem
You should never trust anyone. Maybe you are expecting a remote API to return a piece of data that looks like this.
userData = {
basicInfo: {
name: string;
age: number;
}
}
And you have a component that shows these two piece of data in the following manner.
export const SomeComponent = ( {userData} ) => {
return (
<div>
<div> {userData.basicInfo.name ?? ""}
</div>
)
}
Now for some reason, the developer of the backend thought, okay, let’s change the structure of the data a bit to make it flatter and change it to
userData = {
name: string;
age: number;
}
Now, as soon as they do that, your application will fail on runtime because it doesn’t know that the structure was changed.
You will return to the desk and fix the issue, but your users will be greeted with a crashed application the whole time.
Error: Cant't read name of undefined
One way to avoid a crash like this is
<div> {user?.basicInfo?.name} </div>
But you have to put these ?
sign everywhere which is not so clean, right?
Take advantage of Typescript.
Now let’s define our User model like the following
interface User {
name: string;
age: number;
}
function initUser(options?: Partial<User>): User {
const defaults = {
name: '',
age: 0;
};
return {
...defaults,
...options,
};
}
const p1: User = initPerson();
console.log(p1); // -> {name: '', age: 0}
const p2: User = initPerson({ name: 'Tom'});
console.log(p2); // -> {name: 'Tom', age: 0}
So this initUser method can be used to create an instance of User, and the options
parameter makes it easy to pass parameters if we want.
If we don’t pass anything, we will get back the object with default values.
So before you push the data into the component, you will pass it via the initUser
method and stay chilled.
Or you can use a hook.
const useCleanUserData = (userData: User) => {
return initUser(userData);
}
// inside component
const cleanUserData = useCleanUserData(userData);
This way, we don’t need to worry about whether the API data is clean or not.
You can use this same approach for redux as well. take advantage of the selectors
so that the data is cleaned before they enter into the component.
Have something to say? Get in touch with me via LinkedIn or Personal Website