To help make components easier to re-use and simpler to understand, React and the React ecosystem have been trending towards functional components and hooks. Hooks are a convenient way to add state and side-effects to functional components. They also provide a convenient way for libraries to expose behavior.
While we are generally in favor of hooks, we have some recommendations about how hooks should be used with the Sentry front-end.
If a library provides hooks you should use them. Often this will be the only way
to consume a library. For example
dnd-kit exposes all of its primitives via
hooks and we should use the library the way it was intended to be used.
We don't prefer libraries that use or don't use hooks. Instead favor libraries with cleaner, simpler APIs, and smaller bundle sizes over ones with larger more complex APIs or larger bundle sizes.
useRef hooks are welcome
in any functional component. They are generally a good choice in presentational
components that need a small amount of state, or access to react primitives like
references and context. For example, a component with a slide-out or expandable
useEffect hook is more complex and you need to be careful to track your
dependencies and ensure that subscriptions are canceled through a cleanup
callback. Complex chained applications of
useEffect should be avoided and
'controller' components should remain class-based at this time.
useReducer hook overlaps with state-management which currently
has an undecided future. We would like to avoid yet another state management
pattern, so at this time avoid
As we plan our path away from Reflux, the
useContext hook provides a simpler
implementation option to share state and behavior. When you need to create new
sources of shared state, consider using context and
useContext instead of Reflux.
Additionally the wormhole state management
pattern can be leveraged to
expose shared state and mutation functions.
Custom hooks can be created to share reusable logic in the application. When creating a custom hook,
the function name must follow the convention, starting with "use" (
useTheme, for example)
and it's fine to call other hooks inside of custom hooks.
React hooks have a few rules. Be aware of the rules and limitations that hooks create. We use the ESLint rules to prevent most of the hook rules from being trespassed.
Additionally, we recommend keeping your usage of the
useEffect to a minimum.
useEffect callbacks indicates that you have a component that is
highly stateful and that you should be using a class component instead.
Our foundational view components (
AsyncComponent) are class-based and will be for a long time. Keep this in mind as you build views. You'll
need additional wrapper components to access hooks or convert hook state into
props for your
While hooks can be ergonomic in new code we should avoid rewriting existing code to leverage hooks. Rewriting takes time, exposes us to risk and provides very little end-user value.
If you need to rework a component to consume hooks from a library, then also consider converting from a class to a function component.