Go to content
The Codest
  • About Us
  • Services
  • Our Team
  • Case studies
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About Us
  • Services
  • Our Team
  • Case studies
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
2022-05-09
Software Development

7 Tips and Tricks in React

Mohamed El Amine Daddou

7 Tips and Tricks in React  - Image

Looking for ways to improve your React code? This article contains tips and tricks that every React Developer should know. Let's dive in!

Use TypeScript

Whether we are talking just about react or other libraries, using Typescript will help so much in the efforts to keep your code organized. let’s compare the following Javascript vs Typescript dealing with props types.

import PropTypes from 'prop-types'

function UserCard({ user }) {
    return <div className="user-card">
        {user.firstname}, {user.lastname}
    </div>
}

UserCard.propTypes = {
    user: PropTypes.shape({
        firstname: PropTypes.string.isRequired,
        lastname: PropTypes.string.isRequired
        ...
    })
}

function UserList({ users }) {
    return <div className="user-list">
        {users.map((user) => <UserCard user={user} />)}
    </div>
}

UserList.propTypes = {
    users: PropTypes.arrayOf(PropTypes.shape({
        firstname: PropTypes.string.isRequired,
        lastname: PropTypes.string.isRequired
        ...
    }))
}
interface User {
    firstname: String!
    lastname: String!
    ...
}

function UserCard({ user }: { user: User }) {
    return <div className="user-card">
        {user.firstname}, {user.lastname}
    </div>
}

function UserList({ users }: { users: User[] }) {
    return <div className="user-list">
        {users.map((user) => <UserCard user={user} />)}
    </div>
}

Imagine having all your data schemas as interfaces in a single place and reusing them in all the rest of your code. This will not only help you to avoid typing mistakes but also in case you want to change the schema, you should only change it in a single place.

Besides that, many well-known javascript libraries are migrating to Typescript. eg: AdonisJS

Separate Presentational & Container Components

Separating Presentational & Container Components makes our code easier to test and reason about.

Presentational components are concerned with how things look. It receives its data and behavior from parent components.

Container components are concerned with how things work. They provide the data and behavior to presentational or other container components.

Using this approach allows us to reuse the same presentational components with different data and behavior. In addition to that, it makes our code cleaner and much easier to test.

Check the following example with User Component which is used with different containers that provide different data and behavior.

function BuyerContainer() {
    return <UserComponent
        name="Buyer"
        onClick={() => console.log("Buyer Clicked")}
    />
}

function SellerContainer() {
    return <UserComponent
        name="Seller"
        onClick={() => console.log("Seller Clicked")}
    />
}

function UserComponent({ name, onClick }) {
    return <div onClick={onClick}>{name}</div>
}

Use React Hooks and Functional Components

Functional Components “referred to as Stateless Components before” are no anymore stateless. thanks to React Hooks, now you can useState hook to store state into a functional Component. or even use component lifecycle using useEffect.

Functional components are easy to read and test.

React Core got some other useful hooks that you can explore in Hooks Reference. The amazing thing is that you can also define your custom hooks.

In the following example, we created a custom react hook called useDebounce. Which is used to limit autocomplete API calls when the input text changes.

import { useEffect } from 'react';
import { debounce } from 'lodash';

export default function useDebounce( fn, delay = 500 ) {
    const debounced = useMemoOne( () => debounce( fn, delay ), [
        fn,
        delay,
    ] );
    useEffect( () => () => debounced.cancel(), [ debounced ] );
    return debounced;
}

export default function SearchComponent() 

    const fetchAutoComplete = useDebounce((e) => {
          // Fetch API (optional)
    }, 1000) // 1 sec

  return (
    <div>
      <input type="text" onChange={fetchAutoComplete} />
            {...}
    </div>
  )
}

Besides that, React hooks are a great replacement for **Higher-Order Components (**HoCs).

Styled Component

Styled Component is a library allowing the introduction of Dynamic CSS at the component level. while taking the advantage of ES. It makes your components more predictable and reusable.

Forget about wasting too much time looking for the right class name for an element while trying to avoid using an existing one. With Styled Components ensure that your styles are scoped to the component and auto-generated class names at the build step.

Besides that, it have never been easier to create dynamic CSS. your styles will be generated according props passed to the component. In the following example, the div style is both dependent on the outlined prop and the global theme.

const Wrapper = styled.div`
  border: ${props => props.outlined ? '1px solid' : 'none'};
    background: ${props => props.theme.light ? 'black' : 'white'}
`

The last point about styled-components is that It improves the performance by not loading unnecessary styles of unused components.

Slot Fill Library

Let’s you have defined a layout for your react app. then you want to add a widget in the sidebar only for a specific page. If you didn’t consider that case from the beginning It can require a huge change to the layout.

But using a library like ‣ You can just define a Slot at the Sidebar. Then fill that slot with widgets only for particular pages. that way you will avoid passing flags all along the components tree to access the Sidebar.

It has similar behavior to React Portals which is also a great solution for cases like Modals, Tooltips...

import { Slot, Fill, Provider } from 'react-slot-fill';

const Sidebar = (props) =>
  <div>
    <Slot name="Sidebar.Item" />
  </div>

export default Toolbar;

Sidebar.Item = (props) =>
  <Fill name="Sidebar.Item">
    <button>{ props.label }</button>
  </Fill>

const Widget = () =>
  [
    <Sidebar.Item label="Dashboard Widget" />
  ];

const Page = ({children}) =>
  <Provider>
        <Header /> 
    <Sidebar />
        <Content>{children}</Content>
        <Footer />
  </Provider>

const HomePage = () =>
  <Page>
        a Page without Widjet
    </Page>

const DashboardPage = () =>
  <Page>
        a Page with Widjet
    <Widget />
  </Page>

Higher-Order Components

Even if React hooks replace HOCs in most cases. HoCs are still a great choice concerning hiding complexity from components like providing multiple props to Page Components or conditional rendering (Private routes, loading status ...)

The following example illustrates how can we encapsulate the complexity of both Private routes and Page common props into reusable HoCs applied to all application pages.

Keep in mind that most HoCs cases can be replaced by React Hooks. and that we can by mistake override props by composed HoCs. So please use HoCs only when necessary to keep page components cleaner. otherwise use React Hooks.

function withPrivateRoute(Component) {
    ...
  return function PrivateRoute(props) {
    if (!userConnected) return <Redirect to="/home" />;
    return <Component {...props} />;
  };
}

function withPageProps(Component) {
    ...
  return function privateRoute(props) {
    return <Component
            navigation={navigation}
            currentPath={currentPath}
            currentUser={currentUser}
            {...props}
        />;
  };
}

function ProfilePage({ navigation, currentPath, currentUser}) {
  return <div>
        Profile Page
    </div>
}

export default withPrivateRoute(withPageProps(ProfilePage))

Error Boundaries

Error boundaries are class components, which catch all errors/exceptions thrown at children's level. When declared at the top level it will allow you to do proper error handling by showing an error message and logging the error at a platform monitoring tool like Sentry.

This way you’ll be the first how catch errors and try fixing them before it impacts the user experience.

Note: ErrorBoundaries should be declared at class they do not support functional components.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    logErrorToMySentry(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong ! Contact Admin</h1>;
    }

    return this.props.children; 
  }
} 

cooperation banner

Related articles

Startups

10 Dubai companies worth watching in 2020

Dubai is the heart of the United Arab Emirates with its increasingly prosperous market of global companies and promising startups. Many can boast about their international success and noteworthy products. This market is very...

Tuna Pinar
Software Development

4 Common Web Accessibility Issues to Know

The web is used by millions of different people everyday, one of our main goals as developers is to make the web accessible for everyone. This article will introduce some common web accessibility issues and ways to solve them.

Reda Salmi
Software Development

Javascript Tools in Action

Discover some retrieving JavaScript tools to level up your programming game. Learn more about ESLint, Prettier and Husky!

Reda Salmi
Software Development

Nuxt 3 - a Popular Hybrid Vue Framework

Nuxt 3 is the next generation of the popular hybrid Vue framework, which allows us to use Vue for building server-side rendered applications. Beta version was launched on 12 October 2021, bringing into Nuxt Vue 3, a new intro...

Filip Tobiasz

Subscribe to our knowledge base and stay up to date on the expertise from industry.

About us

Tech company specializing in scaling tech teams for clients and partners thanks to top-class development engineers.

    United Kingdom - Headquarters

  • Office 303B, 182-184 High Street North E6 2JA London, England

    Poland - Local Tech Hubs

  • Business Link High5ive, Pawia 9, 31-154 Kraków, Poland
  • Brain Embassy, Konstruktorska 11, 02-673 Warsaw, Poland
  • Aleja Grunwaldzka 472B, 80-309 Gdańsk, Poland

    The Codest

  • Home
  • About us
  • Services
  • Case studies
  • Know how
  • Careers

    Services

  • PHP development
  • Java development
  • Python development
  • Ruby on Rails development
  • React Developers
  • Vue Developers
  • TypeScript Developers
  • DevOps
  • QA Engineers

    Resources

  • What are top CTOs and CIOs Challenges? [2022 updated]
  • Facts and Myths about Cooperating with External Software Development Partner
  • From the USA to Europe: Why do American startups decide to relocate to Europe
  • Privacy policy
  • Website terms of use

Copyright © 2022 by The Codest. All rights reserved.

We use cookies on the site for marketing, analytical and statistical purposes. By continuing to use, without changing your privacy settings, our site, you consent to the storage of cookies in your browser. You can always change the cookie settings in your browser. You can find more information in our Privacy Policy.