My first  React 'aha' moment. Is this an antipattern?
Tags: react, learning, twitch, antipatterns
Published: 2018-08-20 05:56:13

---
title: My first  React 'aha' moment. Is this an antipattern?
published: true
description: Focussing on building the data for the render function instead of trying to return HTML/JSX from other functions sounds like an antipattern to me.
tags: react,reactjs,learning,twitch,antipatterns
---

Streaming on twitch my first project that uses react, that is not just following a tutorial or online course, is a little daunting but also exhilarating. A benefit of coding projects in the open is that I can more easily share the lessons I am learning.

From the online courses, I had learnt how React works, but I hadn't internalised some of the core concepts of building React projects. I am sure the information was there, it's just that my brain didn't have room to absorb it all.

## Context

My first revelation happened when I started building a logging component for STDOUT and STDERR buffers - like you see on CI tools. I found a random open source example on Travis CI during the stream to see how the markup was put together:

![Random log output from a project on Travis CI](https://thepracticaldev.s3.amazonaws.com/i/3jpnyd4asgg6hapuxkt6.png)

I decided to make the assumption for my simple tool, that STDOUT text should be green and STDERR text should be red. I am in control of the executable being run so I can make silly decisions like this... at least for the time being.

## Antipattern

My first attempt was to push styled spans (`Stdout` and `Stderr`) containing the text into an array stored in the state: 

```jsx
moku.stdout.on('data', data => {
  this.setState({
    output: this.state.output + <Stdout>data.toString()</Stdout>
  });
});

moku.stderr.on('data', data => {
  this.setState({
    output: this.state.output + <Stderr>data.toString()</Stderr>
  });
});

render() {
  return <Container>
    <pre>{this.state.output}</pre>
  </Container>
}
```

The alarm bells went off when I realised that I was storing HTML in the state, not data. I decided that I should think of React component `state` like a datastore, as I wouldn't pump presentational markup into a database (unless it's for a WYSIWYG field) because that restricts what you can do with it. If I store the raw content then I have more flexibility and re-usability.

Choose the path that leads to the most options.

## Data-centric refactor

I decided to store an array of objects, each with a `type` property that I could set to `stdout` or `stderr`, and then use a ternary expression to choose the appropriate component for the object in the `render` function:

 ```jsx
moku.stdout.on('data', data => {
  this.setState({
    output: this.state.output.concat({
      type: 'stdout',
      data: data.toString()
    })
  });
});

moku.stderr.on('data', data => {
  this.setState({
    output: this.state.output.concat({
      type: 'stderr',
      data: data.toString()
    })
  });
});

render() {
  return <Container>
    <pre>
      {this.state.output.map(
        (obj, index) =>
          obj.type === 'stdout' ? (
            <Stdout key={index}>{obj.data}</Stdout>
          ) : (
            <Stderr key={index}>{obj.data}</Stderr>
          )
      )}
    </pre>
  </Container>
}
```

![Showing colour coded output](https://thepracticaldev.s3.amazonaws.com/i/oemvc132zim0kj9pehwz.png)


## Summary

This example is short but it demonstrates what I think of as an antipattern: don't store HTML in the components state. If you disagree then don't stay silent, I am new to React and would appreciate pointers! *Any feedback* on the code would be appreciated.

For my streaming experiment, this helped with writing this article a ton! I was able to scrub back through the video and view the code I had written leading up to the git commit.

## Follow along

Reading this article also saved you from watching my mumbling stream - I am focussing on getting better at presenting live coding. If you want to follow along with my React/Electron progress I mainly steam on Mondays but I'll write up any lessons I've learned here anyway :)

<https://www.twitch.tv/joejamesio>