Code Style

Follow a common code style convention across all projects to maximize reusability and facilitate collaboration.

Write robust, secure and performant applications with more concise and readable code.

Code Style

  • Functional JavaScript.

  • React hooks and context.

  • Separate by concern.

  • Descriptive naming.

  • Declarative programming.

  • Avoid hasty abstractions.

  • Component error boundaries.

Hooks

Hooks solve a wide variety of seemingly unconnected problems in React that we’ve encountered over five years of writing and maintaining tens of thousands of components.

  • It’s hard to reuse stateful logic between components.

  • Complex components become hard to understand.

  • Classes confuse both people and machines

Source https://reactjs.org/docs/hooks-intro.html#motivation

Some advantages of react hooks in conjunction with context api.

  • Prevents prop drilling.

  • Allows to follow single responsibility principle.

  • Improves composability and reusability.

  • More extensibility and maintainability.

  • It's more readable code ( It's easier to reason about and removes clutter ).

  • Easier to debug and test.

File Structure

.
├── App.tsx ................................. Entry point
├── AppProvider.tsx ......................... Group all global providers
├── assets .................................. Global static assets
├── components .............................. Global components
│ ├── Container.tsx
│ ├── Header.tsx
│ └── VideoPlayer/
│ ├── index.tsx
│ ├── useVideoPlayerControls.tsx
│ └── useStreaming.tsx
├── hooks .................................. Global hooks ( typically with context )
│ ├── useWallet.tsx
│ ├── useAuth.tsx
│ ├── useBigHook/
│ │ ├── index.tsx
│ │ ├── Big.tsx
│ │ └── BigHookProvider.tsx
│ └── ...
├── views .................................. Container components ( by feature or route )
│ ├── Admin.tsx
│ ├── Signup.tsx
│ ├── Signin.tsx
│ ├── Container.tsx
│ ├── Header.tsx
│ └── Profile/
│ ├── index.tsx
│ ├── useProfileCustomizations.tsx
│ └── Preferences
│ ├── index.tsx
│ └── usePreferenceMatrix.tsx
├── utils .................................. Utility functions
│ └── index.tsx
└── library ................................ Third party libs, sdks, etc
└── somelib.tsx

Context Hook Pattern

This is ADN of the Hooks Architecture, you will find it everywhere.

The Context API in React allows you share state between different components. Encapsulating Context and Hooks in atomic modules has the following advantages.

  • Prevents prop drilling.

  • Allows to follow the single responsibility principle.

  • Allows portability.

  • Easier to debug and test.

  • Idiomatic.

import React, { useState, useEffect, createContext, useContext, useMemo } from 'react';
import useNotifications from 'hooks/useNotifications'
import { OneOrMoreChildren, CustomHookContextType } from './types';
const customHookDefaults = { setMessage: () => {} };
const CustomHookContext = createContext<CustomHookContextType>(customHookDefaults);
export default function useCustomHook() {
const context = useContext(CustomHookContext);
if (context === undefined) {
throw new Error(
'You must wrap your application with <CustomHookProvider /> in order to useCustomHook().',
);
}
return context;
}
export function CustomHookProvider({ children }: OneOrMoreChildren) {
const [message, setMessage] = useState<Message | null>(null);
const { showNotification } = useNotifications()
const observable = useMemo(()=> createObservable())
useEffect(()=>{
showNotification({message})
},[message])
useEffect(()=>{
observable.subscribe('message', ({message})=> setMessage(message))
return () => observable.unsubscribe()
},[observable])
return (
<CustomHookContext.Provider value={{ setMessage }}>
{children}
</CustomHookContext.Provider>
);
}

Learn more