React is a JavaScript library, and it's the most popular and assiduity- leading frontend development library moment.
JavaScript is a approximately compartmented language, and as a result, it catches runtime. The result of this is that JavaScript crimes are caught veritably late and this can lead to nasty bugs. As a JavaScript library, Reply inherits this problem.
Clean law is a harmonious style of programming that makes your law easier to write, read, and maintain. Anyone can write law that a computer can understand but good inventors write clean law – law that humans can understand.
Clean law is a anthology- concentrated development style that improves our software quality and maintainability.
Writing clean Law involves writing canons with clear and simple design patterns that makes it easy for humans to read, test and maintain. Accordingly, clean law can lower the cost of software development. And this is because the principles involved in writing clean law, eliminates specialized debts.
In this composition, we'd look at some useful patterns to use when working with React and TypeScript.
💡 To make it easier for your platoon to keep codebase healthy and prioritise specialized debt work, try out Stepsize VS Code and JetBrains extensions. They help Masterminds produce specialized issues, add them to the sprint, and address tech debt continuously-without leaving the editor.
Now let’s learn about the ten useful patterns to apply when using React and Typescript
Writing clean code involves writing codes with clear and simple design patterns that makes it easy for humans to read, test and maintain. Consequently, clean code can lower the cost of software development. And this is because the principles involved in writing clean code, eliminates technical debts.
In this article, we would look at some useful patterns to use when working with React and TypeScript.
Read more :- IT Skills to learn in 2022.
💡 To make it easier for your team to keep codebase healthy and prioritise technical debt work, try out Stepsize VS Code and JetBrains extensions. They help Engineers create technical issues, add them to the sprint, and address tech debt continuously - without leaving the editor.
Now let’s learn about the ten useful patterns to apply when using React and Typescript:
1. Use Default import to import React
Consider the code below:
While the code above works, it is confusing and not a good practice to import all the contents of React if we are not using them. A better pattern is to use default export as seen below:
With this approach, we can destructure what we need from the react
module instead of importing all the contents.
Note: To use this option, we need to configure the tsconfig.json
file as seen below:
In the code above, by setting esModuleInterop
to true
we enable [allowSyntheticDefaultImports](http://allowsyntheticdefaultimports)
which is important for TypeScript to support our syntax.
2. Declare types before runtime implementation
Consider the code below:
The code above can be cleaner and more readable if we separate the runtime and compile-time declarations. And this is done by declaring the types — the compile type declarations first.
Consider the code below:
Now at first glance, a developer knows what the component API looks like since the first line of the code clearly shows this.
Also, we have separated our compile-time declarations from our runtime declarations.
3. Always provide explicit type of children Props
TypeScript mirrors how React handles children props by annotating it as optional in the react.d.ts
for both functional and class components. Consequently, we are required to explicitly provide a type for the children
props. However, it is best practice to always explicitly annotate children
props with a type. This is useful in cases where we want to use children
for content projection, and if our component does not use it, we can simply annotate it with the never
type.
Consider the code below:
Below are some valid types to annotate the children props:
- ReactNode | ReactChild | ReactElement
- For primitive we can use string | number | boolean
- Object and Arrays are also valid types
- never | null | undefined – Note: null and undefined are not recommended
4. Use type inference for defining a component state or DefaultProps
Consider the code below:
While the code above works we can refactor it for the following improvements:
To enable TypeScript’s type system to correctly infer readonly
types such as DefaultProps
and initialState
To prevent developer bugs arising from accidentally setting state: this.state = {}
Consider the code below:
In the code above, by freezing the DefaultProps
and initialState
the TypeScript type system can now infer them as readonly
types.
Also, by marking both static defaultProps
and state as readonly
within the class we eliminate the possibility of runtime errors arising from setting state as mentioned above.
5. Use type alias instead of interface for declaring Props/State
While interface
can be used, for consistency and clearness sake it is best to use type alias as there are cases where interface
cannot work. For instance, in the previous example, we refactored our code to enable TypeScript’s type system to correctly infer readonly types by defining state type from implementation. We cannot use interface
with this pattern as seen in the code below:
Also, we cannot extend interface
with types
created by unions and intersection, so in these cases, we would have to use type
alias.
6. Don’t use method declaration within interface/type alias
This ensures pattern consistency in our code as all members of type/inference are declared in the same way.
Also, --strictFunctionTypes
works only when comparing functions and does not apply to methods. You can get further explanation from this TS issue.
Consider the code below:
7. Don’t use FunctionComponent
Or its shorthand FC
to define a function component!
When using TypeScript with React, functional components can be written in two ways:
- As normal functions as seen in the code below:
- Using the
React.FC
or React.FunctionComponent
as seen below: https://gist.github.com/lawrenceagles/310dd40107547a3d3ed08ae782f767cf
Using FC
provides some advantages such as type-checking and autocomplete for static properties like displayName
, propTypes
, and defaultProps
. But it has a known issue of breaking defaultProps and other props: propTypes
, contextTypes
, displayName
.
FC
also provides an implicit type for children
prop which also have known issues.
Also, as discussed earlier a component API should be explicit so an implicit type for children
prop is not the best.
8. Don’t use constructor for class components
With the new class fields proposal, there is no need to use constructors in JavaScript classes anymore. Using constructors involves calling super()
and passing props
and this introduces unnecessary boilerplate plate and complexity.
We can write cleaner and more maintainable React class components by using class fields as seen below:
In the code above, we see that using class fields involves less boilerplate and we don’t have to deal with the this
variable.
9. Don’t use public accessor within classes
Consider the code below:
Since all members in a class are public
by default and at runtime, there is no need to add extra boilerplate by explicitly using the public
keyword.
Instead, use the pattern below:
10. Don’t use private accessor within Component class
Consider the code below:
In the code above, the private accessor only makes the fetchProfileByID
method private
on compile-time since it it is simply a TypeScript emulation. However, at runtime, the fetchProfileByID
method is still public.
There are different ways to make the properties/methods private in a JavaScript class private one is to use the underscore (_) naming convention as seen below:
While this does not really make the fetchProfileByID
method private it does a good job of communicating our intention to fellow developers that the specified method should be treated as a private method. Other techniques involve using weakmaps, symbols, and scoped variables.
But with the new ECMAScript class fields proposal we can do this easily and gracefully by using private fields as seen below:
And TypeScript supports the new JavaScript syntax for private fields from version 3.8 and above.
Bonus: Don’t use enum
Although enum
is a reserved word in JavaScript, using enum
is not a standard idiomatic JavaScript pattern.
But if you are coming from a language like C#
or JAVA
it might be very tempting to use enums. However, there are better patterns such as using compile type literals as seen below:
Conclusion
Using TypeScript no doubt adds a lot of extra boilerplate to your code but the benefit is more than worth it.
To make your code cleaner and better don't forget to implement a robust TODO/issue process. It'll help your Engineering team get visibility on technical debt, collaborate on codebase issues and plan sprints better.
Post a Comment