Creating a Users component
Published: 2021-08-02 23:13:21

In this post:
1. [The Goal](#the-goal)
2. [The Problem](#the-problem)
3. [The Options](#the-options)
4. [The Decision](#the-decision)
5. [The Plan](#the-plan)

###The Goal
Add a *users list* to the two *feed* pages.

One of the things that I enjoy most about software engineering is working out the interactions between the many moving parts of a web application, and identifying efficiencies, inefficiencies, and opportunities, and then either building or re-factoring code to execute on those good ideas.

That's what I'm thinking about as I look at the following code which renders an html page which I'll also paste below:

```javascript

const Feed = (props) => {

  const [postData, setPostData] = useState([]);
  const [feedView, setFeedView] = useState(null);

  const path = props.match.path;

  useEffect(() => {

    if (path === "/all"){
      httpHandler.getFeedAllUsers((err, data)=>{
      setPostData(data)
      setFeedView(path)
      })
    } else if (path === "/:user/feed"){
        const user = props.match.params.user
        httpHandler.getFeedOneUser(user, (err, data)=>{
        setPostData(data)
        setFeedView(path)
      })

    }
  }, [props.feedView])

    if (postData){

      return(
        <div id='feed'>
          {postData.map(post=>
            <div className='post' >
              <>
              <h3 className='post-title'>{post.title}</h3>
              <div className='post-content'>
                <Link to={`/${post.author.userName}/feed`}>
                  <div><strong>{post.author.userName}</strong></div>
                </Link>
                <div>{post.text}</div>
               </div>
              </>
            </div>
          )}
        </div>
      )
    } else {
      return <div>No posts</div>
    }
}
```
What it looks like:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/klm580smri0fier9obbq.png)

###The Problem
Right now, I'm 100% feed. That is, I've managed to render two different feeds with one component - one for all users and one for a specific user. So the feed component is all I've got and it's doing two jobs

1. Serving all content
2. Fetching its own data

**But now, I want to add a users list that uses a sub-set of the feed data** (Since I have a non-normalized schema, all authors are attached to posts. To get all authors, I need to pull all posts).

###The Options
I have two options.

1. 'Quick and Easy': ties the post feed and users into the same component, and requires little new code.
2. 'Slow and Hard': refactor and create a custom hook that makes data calls and feeds separate *user* and *feed* components.

####Quick and Easy:
As I mentioned above, the user data is bound inside of the post data. I have two options, then, for getting all distinct users:

1. Making a separate call to the database using Model.distinct()
2. Filtering the post data either server- or client-side to extract user names.

**Pros:**
- Quick and Easy!

**Cons:**
- Extra request and extra database query.
- Possibly delaying the inevitable (the custom-data-hook-refactor), and creating work that I'll need to unwind.

**Slow and Hard**

Instead of building *users* into *feed,* (or putting them both into a parent-component that is based on *feed*), I would build a new separate component.

Why? It's likely that I'll end up using this list separately from feeds elsewhere on the site).

How? I'd make a new custom hook that makes its own data queries and feeds that to both *user list* (a proto-*friend list*) and to *feed*.

**Pros**:
- Flexibility/modularity/DRY
- Good, no GREAT, practice with hooks.

**Cons**:
- Time-expensive refactoring
- I don't know what I don't know.
- This might end up not being the end-solution. I'd hate to end up refactoring this refactor.

###The Decision
I'm going to need to sit with this and figure out which direction to travel...
---
Twenty minutes later...
---
I've come to a decision. I'm not totally happy with it, but I believe it's the right move.

I'm glad I took the time to step back, because I realized that I needed to think about my real goal. It's not to build a blog platform. My goal is to build enough to attract a team. And my most expensive resource right now is time.

So I decided to go with the first option. Because it better aligns with my business objectives.

###The Plan
I'm going to roll the list of users into the feed. Now the lazy way to do this is to just write a few more divs in the return statement.

But I'm not doing this to be lazy, I'm doing this to be efficient, so I'll create separate *feed* and *user* components and embed those in a parent component.

Again, I ask myself: does it meet business objectives? My objectives are: speed and solid engineering practices. I believe this is the correct solution.

There's very little overhead to doing this new thing. It's almost free, and does not make things unreasonably complicated if I want to unwind it.

I'm good to go.