DEV Community

Cover image for Pure Components, Interfaces and Logic Hooks.
Charbel Rami
Charbel Rami

Posted on

Pure Components, Interfaces and Logic Hooks.

Available on Medium

This architecture is divisible into three components, Pure Components, Interfaces and Logic Hooks. It is a variant on the Presentational and Container Components pattern described by Dan Abramov, now considering the existence of Hooks.

Pure Components


Interface

Logic Hook

Interfaces are mainly concerned with how information should be shared between Logic Hooks and with Pure Components. Interfaces receive functions and values provided by Logic Hooks and share them with other Logic Hooks or pass them as props to Pure Components.

Logic Hooks are similar to Container Components. Pure Components are similar to Presentational Components. But they differ on some points.

Comparison

Presentational Components and Pure Components

From Dan's post:
"My presentational components:

  • Are concerned with how things look.
  • May contain both presentational and container components** inside, and usually have some DOM markup and styles of their own.
  • Often allow containment via this.props.children.
  • Have no dependencies on the rest of the app, such as Flux actions or stores.
  • Don't specify how the data is loaded or mutated.
  • Receive data and callbacks exclusively via props.
  • Rarely have their own state (when they do, it's UI state rather than data).
  • Are written as functional components unless they need state, lifecycle hooks, or performance optimizations.
  • Examples: Page, Sidebar, Story, UserInfo, List."

My Pure Components:

  • Same ("Are concerned with how things look.").
  • May contain other Pure Components, markup, and styles.
  • Same ("Often allow containment via this.props.children.") props.children.
  • Same ("Have no dependencies on the rest of the app, such as Flux actions or stores.").
  • Same ("Don't specify how the data is loaded or mutated.").
  • Same ("Receive data and callbacks exclusively via props.").
  • Don't have their own state. They should receive, as props, a local state provided by a Logic Hook through an Interface.
  • Are written as functional components.
  • Same ("Examples: Page, Sidebar, Story, UserInfo, List.").

Container Components and Logic Hooks

From Dan's post:
"My container components:

  • Are concerned with how things work.
  • May contain both presentational and container components** inside but usually don't have any DOM markup of their own except for some wrapping divs, and never have any styles.
  • Provide the data and behavior to presentational or other container components.
  • Call Flux actions and provide these as callbacks to the presentational components.
  • Are often stateful, as they tend to serve as data sources.
  • Are usually generated using higher order components such as connect()from React Redux, createContainer() from Relay, or Container.create()from Flux Utils, rather than written by hand.
  • Examples: UserPage, FollowersSidebar, StoryContainer, FollowedUserList."

My Logic Hooks:

  • Same ("Are concerned with how things work.").
  • Shouldn't contain other components, markup or styles.
  • Provide the data and behavior to Interfaces.
  • Call Flux actions and provide these as callbacks to Interfaces.
  • Same ("Are often stateful, as they tend to serve as data sources.").
  • n/a ("Are usually generated using higher order components such as connect()…").
  • Examples: useUser, useFollowers, useStory, useFollowed.

Just like the Presentational and Container Component pattern, this separation makes it easier to replace or delete code. If you wanted to replace your state container, you would need to update your Logic Hooks, but not your Interfaces or Pure Components. But it is particularly useful if your application has different UI flows, hence the name "Interface". For example, you could use the same Logic Hooks for a React and React Native application with different Interfaces. These Interfaces would receive information from the same Logic Hooks, and accommodate Pure Components in distinct ways.

Full example

Top comments (7)

Collapse
 
kayis profile image
K • Edited

Nit: you used the list code two times.

otherwise good post, while I wouldn't use the name "interface" for this concept, because it could be confused also I'd prefer a Redux-less solution, probably created with useReducer or something

Collapse
 
charbelrami profile image
Charbel Rami • Edited

Thanks! I chose the name 'Interface' because it's the layer that connects the other two components and it represents the user interface. I'd appreciate any suggestions for a better name. I used Redux to show the responsibility of the Logic Hook, but it could be replaced by useReducer or anything else.

Collapse
 
jonocodes profile image
Jonathan Stiansen

Maybe facade? That's a good pattern name that does similar things here.

Collapse
 
dukemai profile image
dukemai • Edited

thanks for introducing a fresh way to have state in react app. I like the idea to have logic hooks so it looks cleaner

Collapse
 
charbelrami profile image
Charbel Rami

Thanks!

Collapse
 
bytegasm profile image
Bytegasm!

Love the separation of concerns. However, I wonder what are the edge cases with this pattern.

Collapse
 
charbelrami profile image
Charbel Rami

Thanks! Not sure about edge cases, they may appear over time.