How to think in React

If you're a back-end developer getting into frontend dev space via React, the UI library can feel strangely weird or just outright foreign. Or if you're a front-end developer tasked with a React project for the first time, the library has the potential to make you question everything you've ever known.


This is a companion discussion topic for the original entry at https://triplebyte.com/blog/how-to-think-in-react

For anyone reading this who is new to React, I assert that the above process is not the ideal starting point.
Perhaps I have been working in React for too long to remember what just starting out feels like, but it’s important to focus on the fact that React takes the perspective of UI = f(state). If UI is a function of state, how does state change? How does the new state change the UI?

Data isn’t the only part of a web application. Dividing your components into single responsibility doesn’t mean just isolating the parts of your data or UI, but also identifying the behaviors, styles, and states that go along with them as well as how unique those parts are to the data at hand.

I would suggest that you perform a pre-order depth-first exploration. This suggested process is one that I created while teaching React and can obviously be customized as you become more comfortable with the framework. Hopefully, it will start you off with a greater understanding of what you’re building and empower you to follow outside-in testing methodologies with ease (something that I find especially valuable on the front-end).

The exploration should ask:

  1. Is this thing an HTML element?
    • If no
      1. what components make up this thing?
    • If yes
      1. should I source a non-native version of this HTML element and, if so, what components do I need? (this will most commonly apply to inputs, tables, and forms and would include rolling your own or importing from an npm module)
  2. Are there any behaviors associated with this thing?
    • If yes
      1. What behaviors do you expect?
      2. What triggers each of those behaviors?
      3. What state is required to support each of those behaviors?
      4. How do these behaviors impact the layout or style?
  3. Is there any state required by this thing that isn’t identified by the behaviors? (this step identifies if the state is actually owned by this component or by a parent)
    • If yes
      1. What state is required?
      2. Where does this state come from (self, parent, server, etc)?
      3. How do changes to this state change the UI?
      4. What behaviors are able to change this state and what are their triggers?
      5. Is this state that I need to manage myself? (DOM elements can have their own internal state and if this “state” comes from the parent, it may not need to be managed locally, which makes it props only)
  4. Is there any change to the UI that isn’t identified above?
    • If yes
      1. What additional changes to the UI are there and what conditions predicate them?
  5. If the answer in step 1 resulted in you needing to create additional subcomponents, repeat this process for every “child” component/element, but also consider the answers from the direct parent as you progress

For example:

  1. Is a filterable table an HTML element?
    • No
      1. what components make up this thing? - a text input, a table
  2. Are there any behaviors associated with this thing?
    • Yes
      1. What behaviors do you expect? - filtering
      2. What triggers each of those behaviors? - typing into the text input
      3. What state is required to support each of those behaviors? - the filtering value
      4. How do these behaviors impact the layout or style? - they don’t
  3. Is there any state required by this thing that isn’t identified by the behaviors?
    • No
  4. Is there any change to the UI that isn’t identified above?
    • Yes
      1. What additional changes to the UI are there and what conditions predicate them? - If no items are found, we should show a message rather than a table
  5. If the answer in step 1 resulted in you needing to create additional subcomponents, repeat this process for every “child” component/element, but also consider the answers from the direct parent as you progress
  6. Is a text input an HTML element?
    • Yes
      1. should I source a non-native version of this HTML element and, if so, what components do I need? - no
  7. Are there any behaviors associated with this thing?
    • Yes
      1. What behaviors do you expect? - filtering the table (handled by the parent)
      2. What triggers each of those behaviors? - a user typing into this element
      3. What state is required to support each of those behaviors? - current value
      4. How do these behaviors impact the layout or style? - changing the sibling’s contents
  8. Is there any state required by this thing that isn’t identified by the behaviors?
    • No
  9. Is there any change to the UI that isn’t identified above?
    • No
  10. Is a table an HTML element?
    • Yes
      1. Should I source a non-native version of this HTML element and, if so, what components do I need? - yes, a table (native HTML tables can be a pain)
  11. Are there any behaviors associated with this thing?
    • No
  12. Is there any state required by this thing that isn’t identified by the behaviors?
    • Yes
      1. What state is required? - the data to populate the table
      2. How do changes to this state change the UI? - changes number of rows rendered
      3. What behaviors are able to change this state and what are their triggers? - the filtering of the data
      4. Is this state that I need to manage myself? - no, the parent manages it
  13. Is there any change to the UI that isn’t identified above?
    • No