React assumes that every component you write is a pure function¹ - given the same input, it should return the same output. This makes components predictable, testable and easy to work with.

To help with this, React encourages encapsulation and low coupling - each component should define its own logic and expose only what's needed to change its behaviour².

A React component is most effective when it's self-contained with props that are easy to manage, descriptive and predictable.

Using Typescript enforces this predictability by clearly documenting the props of a component. It does this by restricting the type of data that can be given to each prop, which is also why using the any type should be avoided, as it removes type safety by allowing anything³.

Although it may feel convenient and harmless, reusing an API type for a component can misrepresent what the component actually needs. This can lead to added, and often unnecessary, complexity and cause the component to be misunderstood or misused.

Problematic Example

Consider the following interfaces representing API data for a blog post:

interface Author {
   avatarUrl: string;
   username: string;
   email: string;
   createdDate: string;
   isEnabled: boolean;
}

interface BlogPostApiData {
   title: string;
   description: string;
   author: Author;
   createdDate: Date;
   lastModifiedDate: Date;
}

const BlogPostSummary = (props: BlogPostApiData) => {
   . . .
}

Now, let's say we have a simple component that displays a summary of the blog post: its title, the author's name and created date. You might be tempted to reuse the above interfaces for this component because it contains everything you need.

However, it also contains more than you need.

If another developer sees that your component accepts PostData, they may expect it to support showing the description, last modified date or the authors avatar. When they try to use them, nothing happens.

Why is this a problem?

  • The component is misleading - the interface suggest it does more than it actually does.
  • Maintainability is reduced - if the API structure changes, then the component may need to change as well, even if its core functionality remains the same.
  • It encourages misuse - developers may be tempted to add the 'missing' support for unrelated functionality.
  • Confusing or awkward data structures - names used at the API level may not be intuitive for the component, making props harder to work with. Accessing data might also feel needlessly verbose (e.g. props.author.username vs. props.username, if only the username of the author is needed).

Better Example

Let's revisit our simple component. As a reminder, it needs to display the blog posts's title, authors name and date it was posted.

This time, instead of reusing the API interface, we create a new one dedicated to the components specific needs.

interface BlogPostSummaryProps {
   title: string;
   authorName: string;
   datePosted: string;
}

const BlogPostSummary = (props: BlogPostSummaryProps) => {
   . . .
}

Why is this better?

  • Clear purpose - the component only accepts the data it needs, making its intent explicit. Developers will also be less tempted to extend it to support unrelated functionality.
  • More resistant to change - the component is self-contained and doesn't rely on external data structures, allowing it to remain the same even if its surrounding logic changes.
  • Easier to extend - for the same reason, new functionality can be added without affecting surrounding logic.
  • Better reusability - the component defines its own data, allowing it to be reused in more ways and with different data sources.

Sources

  1. React.dev. (2025). Keeping Components Pure – React. [online] Available at: https://react.dev/learn/keeping-components-pure. [Accessed 31 Jan. 2025]
  2. react.dev. (n.d.). Passing Props to a Component – React. [online] Available at: https://react.dev/learn/passing-props-to-a-component. [Accessed 31 Jan. 2025]
  3. W3Schools (n.d.). TypeScript Special Types. [online] Available at: https://www.w3schools.com/typescript/typescript_special_types.php. [Accessed 31 Jan. 2025]

Author Of article : Matt Elcock Read full article