common mistakes

Ineffective Access to Component Props

The code provided in this article is simplified as much as possible to avoid overwhelming the reader with code and to convey the essence of the problem and its solution. In interactive examples, heading tags (`h1...h6`) are replaced with span tags to prevent potential conflicts with the main page structure.

In JavaScript and, consequently, in React, the concept of objects is often used to store component property values. Inside an object, many different values can be passed, which may not be immediately obvious to the component. This complicates working with a specific component, making code reading and maintenance more difficult.

Let's consider the following example:

Code implementation
1interface ChildComponentProps {
2 title: string;
3 content: string;
4}
5
6const ChildComponent: FC<ChildComponentProps> = (props) => {
7 return (
8 <div>
9 <h3>{props.title}</h3>
10 <p>{props.content}</p>
11 </div>
12 );
13};
14
15const ParentComponent: FC = () => {
16 const data = {
17 title: 'Title',
18 content: 'Paragraph content',
19 };
20
21 return (
22 <ChildComponent
23 title={data.title}
24 content={data.content}
25 />
26 );
27};
28

In this example, the values of props.title and props.content are extracted directly from the props object within JSX. Although this approach works, it isn't optimal as it complicates code reading and understanding, especially when dealing with multiple props.

The best way to solve this problem is to use destructuring. This allows extracting object properties and assigning them to variables with the same names. Let's improve our code:

Code implementation
1interface ChildComponentProps {
2 title: string;
3 content: string;
4}
5
6const ChildComponent: FC<ChildComponentProps> = (props) => {
7 const { title, content } = props;
8
9 return (
10 <div>
11 <h3>{title}</h3>
12 <p>{content}</p>
13 </div>
14 );
15};
16
17const ParentComponent: FC = () => {
18 const data = {
19 title: 'Title',
20 content: 'Paragraph content',
21 };
22
23 return (
24 <ChildComponent
25 title={data.title}
26 content={data.content}
27 />
28 );
29};
30

This code is already easier to read as we explicitly define variables title and content from props. But we can do even better by destructuring properties directly in the function parameters:

Code implementation
1interface ChildComponentProps {
2 title: string;
3 content: string;
4}
5
6const ChildComponent: FC<ChildComponentProps> = ({ title, content }) => {
7 return (
8 <div>
9 <h3>{title}</h3>
10 <p>{content}</p>
11 </div>
12 );
13};
14
15const ParentComponent: FC = () => {
16 const data = {
17 title: 'Title',
18 content: 'Paragraph content',
19 };
20
21 return (
22 <ChildComponent
23 title={data.title}
24 content={data.content}
25 />
26 );
27};
28

By using this approach, we make our component as readable and understandable as possible. Destructuring in function parameters immediately shows which properties the component expects.

Using destructuring improves code readability, enhances code structure and maintainability, making it more understandable for other developers and for you in the future. You immediately see which properties are used in the component. This is useful when you need to modify or extend the component in the future. You don't need to search through the function body to understand which properties are available.

Our examples are written in TypeScript, which certainly makes the code more obvious, but imagine code that doesn't use either TypeScript or destructuring. It would greatly complicate the work, thus slowing down the development process, which is critical in our dynamic world.

Last updated on by @skrykateSuggest an improvement on Github repository.