React Native — Coding Best Practices

CODING STANDARD

When it comes to coding standards for React Native, it is important to follow best practices to ensure code readability, maintainability and consistency within your project. While there are no official coding standards for React Native. But, you can adopt widely accepted conventions and guidelines. 

Here are some recommendations:

BASIC RULES
  1. Always use const or let to declare variables. Use const by default, unless a variable needs to be reassigned.
  2. Always use functional components.
  3. No nested components or getComponent inside the render method. Always try to separate the components if possible!
NAMING
  1. PascalCase: This is the most common naming convention for React Native components. It involves capitalizing the first letter of each word in the name.
  2. camelCase: This naming convention is less common than PascalCase, but it is still sometimes used. It involves capitalizing the first letter of the first word in the name and then capitalizing the first letter of each subsequent word.
  3. CONSTANT_CASE: This naming convention is used to define global constants and enums.

Example:

// CONSTANT_CASE

const PRIMARY_COLOR = '#FF0000';

const FONT_SIZE_LARGE = 18;

const API_ENDPOINT = 'https://api.example.com';

// PascalCase & camelCase

interface Employee {

  fullName: string;

  employeeId: string;

}

TYPE SYSTEM

Should always define type as possible. any type is restricted in any case.

INTERFACE (TYPESCRIPT)

The interface is a way to define the shape or structure of an object.

Example:

interface Person {

  name: string;

  age: number;

}

Benefits of using interfaces in TypeScript:

Type safety: Interfaces help to ensure the type safety of TypeScript code. This means that you can be confident that objects are of the correct type, and that methods are called with the correct parameters.

Reusability: Interfaces can be used to make code more reusable. By defining the structure of an object in an interface, you can reuse that structure in multiple classes.

Clarity: Interfaces can help to improve the clarity of your code. By defining the structure of an object in an interface, you can make it easier to understand how objects are used.

SOURCE ORGANIZATION
IMPORTS
  1. Use absolute path as possible.
  2. Use relative path when referring to files within the same locates

EXPORTS

  1. Prefer use of file scope for namespacing, as well as named exports.
  2. Use the same name when importing a default module.

STYLES

Use base styles as possible.

  • Example:
const baseStyle = StyleSheet.create({

  flex: {

    flex: 1,

  },

  justifyContentCenter: {

    justifyContent: 'center',

  },

  centralize: {

    justifyContent: 'center',

    alignItems: 'center',

  },

  p4: {

    padding: 4,

  },

  m8: {

    margin: 8,

  },

});

Always create separate style files when creating a new component.

Example:

const styles = StyleSheet.create({

  width: {

    width: 16

  },

  height: {

    height: 16,

  },

  successMessage: {

    fontFamily: 'Inter-Medium',

    color: 'green'

  },

  errorMessage: {

    fontFamily: 'Inter-Regular',

    color: 'red'

  },

  textAlignCenter: {

    textAlign: 'center',

  },

});

export default styles;

Don’t use inline styling. Always use StyleSheet to create a styles object.

// Bad: No inline style
<Text style={{ fontSize: 16, color: 'red' }}>Hello, React Native!</Text>

// Good

<Text style={styles.successMessage}>Hello, React Native!</Text>
CONSISTENCY
  1. Consider using the arrow function when declaring a function instead of a traditional function.
  2. You can use arrow functions for various purposes, including event handlers, functional components, and more.

Example:

// Event Handlers

<Button onPress={() => console.log('Button clicked!')} title="Click me" />

// functional components

const MyComponent = () => {

  return <Text>Hello, React Native!</Text>;

};
HOOKS API
  1. useCallback/useMemo Should use when needing to memoization previous function/value.
  2. Only use it when declaring function/value has dependency is changed.

Example: useCallback

// Bad

const FooComponent = () => {

  const onPress = () => {

    // onPress is newly created in every render instead of reusing the previous one

  };

  return <Bar onPress={onPress} />

} 

// Good

const FooComponent = ({a, b}) => {

  const onPress = useCallback(() => {

    // onPress is reused if a & b don't change.

  },[a, b]); 

  return <Bar onPress={onPress} />

}

Example: useCallback

// Bad

 const calculation = expensiveCalculation(count);

// Good

const calculation = useMemo(() => expensiveCalculation(count), [count]);

const expensiveCalculation = (num) => {

  for (let i = 0; i < 1000000000; i++) {

    num += 1;

  }

  return num;

};
SELECTORS

Try to use selector to pick a value in the redux state.

Example:

function TodoList() {

  // This anonymous arrow function is a selector!

  const todos = useSelector(state => state.todos)

}

FOLDER STRUCTURE

src: This folder is the main container of all the code inside your application.
components: Folder to store any common component that you use through your app (such as a generic button)
screens: Folder that contains all your application screens/features.
navigations: Folder to store the navigators.
services: Folder to store all common services used in the application.
utils: Folder to store any common function such as calculate radius, different date formatting functions and constants.
types: Folder to store all enum and interface used in application.
redux: Folder to store action, reducer and redux store.
App.js: Main component that starts your whole app.
index.js: Entry point of your application as per React-Native standards.
assets: Asset folder to store all images, vectors, fonts, etc.


Create and manage the environment variables files in root folder (.env)

Example:

- src

  - components

    - Button.js

    - Text.js

  - screens

    - HomeScreen.js

    - ProfileScreen.js

  - navigations

    - AppNavigator.js

    - TabNavigator.js

  - services

    - api.js

    - http.js

  - utils

    - helpers.js

    - constants.js

  - types

    - enums

      - userStatus.js

    - interfaces

      - userData.ts

  - redux

    - action.js

    - store.js

    - reducer.js

  - App.js

  - index.js

- assets

  - images

    - png

      - logo.png

    - svg

      - logo.svg

  - fonts

    - Roboto-Regular.ttf

SUMMARY

Following consistent coding standards and best practices in React Native development can greatly improve code quality, maintainability, and collaboration among developers.

Hope this blog post provides a useful guide to help you establish coding standards and project structure for your React Native projects. 

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.