Blog

Here we share our experiences, ideas, tips, and thoughts on React, Angular, Industry in general, and some other things.

Redux Bad Practices: Nested State

Adam Klein

Complex applications usually deal with data structures that have associations, e. g. posts that have comments.

bad approach would be to save the data nested in the state:

posts:
  id: 1
  title: 'Better Redux'
  comments:
    id: 2
    text: 'Great article!'

good approach would be to flatten the state and operate with foreign IDs on the data.

posts:
  id: 1
  title: 'Better Redux'
comments:
  id: 2
  postId: 1
  text: 'Great article!'

There are multiple disadvantages of storing a nested state.

Nested data structures are harder to maintain and explore. Nesting doesn’t allow for sharing associated models (many to many), for example comments can be on posts, and on images.

It’s easier to gain good performance with flat state, because the optimization works on comparing references. Changing a nested comment will force the change of the entire post object.

It’s also harder to find a nested object by ID; you’ll need to pass around the full path to the object.

And last but not least, it’s easier to debug the state when it’s fairly flat.

Robert C. Martin on Effective Estimation

Ilya Gelman

Estimating projects and tasks in something that many developers have to do all the time. No matter how many times we do that, giving perfect estimates is always hard or close to impossible.

Famous Robert C. Martin (uncle Bob) talks at YOW! 2016 on how to actually estimate projects without lying. This talk is important not just for developers, but also for many project managers.

On Thursdays we post videos that we believe are worth watching and that can make you a better front-end developer. Have such a video to share? Share with us

Redux Bad Practices: Duplicate State

Adam Klein

Let’s say you need to display a filtered list of products.

bad approach would be to save the filtered list on each filter change in a component’s state or in a different key in a Redux store.

onFilterChange(filter) {
  this.setState({
    filteredProducts: this.props.products.filter(...)
  })
}

good approach would be to use cached selectors with reselect:

mapStateToProps = (state) => ({
  filteredProducts: filteredProductsSelector(state)
})

Or calculate the computed data on render if it’s not shared and runs fast:

render() {
  const filteredProducts = this.props.products.filter(...);

  return <div>{ filteredProducts.map(...) }</div>;
}

Redux offers you a mechanism for a single source of truth. If you save different representations of the same data in your store or in component’s state you are violating that principal. You should only save raw data once, and calculate everything that can be derived from it.

Designing Mimic UI, Part 2

Ilya Birman

Earlier in part 1, I’ve covered the general organization of Mimic application, including the status bar, Quick Edit and opening and closing of the full editor.

Now let’s see how went the main work on the full editor. The “Mimic” button moves to the bottom to match with the position in Quick Edit. Settings follow:

Take 6. The “Mimic” buttons moves down

The close button is added to the top right corner for the convenience, but pressing “Mimic” also closes the editor. Also notice the “+” button in the bottom left corner. I had to add an ability to set up a new mock without the need to capture a request from the developed application. In the list on the left a new “M” symbol is added for mocked requests and also a way to represent many similar requests (the number “18”).

The next thing to think about is the way to edit not the response, but the mocked request itself. So the previously designed interface becomes part of the Response tab, and a new Request tab gets added:

Take 7. Added Request and Response tabs

Also, the list on the left becomes wider to fit longer requests. And the checkbox moves to the right to reflect the recent change in the Quick Edit bar.

The request editor gets the ability to change the method and the URI, to set up custom headers and body and, most importantly, use wildcards:

Take 7. The debut of the request editor

So, on the left the log is a separate thing from the mocks list. But it feels increasingly strange.

First of all, the log will obviously be much longer than four items. It would be inconvenient to work with in this small area. Second, there is a logical problem. The log is for the developer to quickly pick a recent real request to replace with a mock. It also makes sense for the previously mocked requests to appear in the log, in blue and with an “M” symbol — as you see in the picture. However, if we show them, they have to be editable and there should be a way to enable and disable them. But how do you disable a mock that has been already used in the past and logged? Or what if I had several requests like this already, and some of them were mocked, and I disable one of these mocks from the past? This is strange and unpredictable. The list becomes a mixed bag that is both a log and a mock configurator. I have to do something with it.

So it is time to re-think the left list. I separate the two lists:

Take 10. The separation of the mocks and the log

The mocks list gets a lot of though this time. I add grouping, make the list much more informative and move the checkboxes to the left, where they belong. Icons for removing a mock (the minus) and search (the loupe) are added. The tabs for Request and Response move to the top. On the right, the secondary tabs for Headers and Body are added, and everything gets reorganized in a more dense way.

This design has a small problem. The loupe icon of the search is next to minus and plus icons, which makes it look like a zoom control. I have to move it somewhere.

Also, it makes sense to remove the Mimic button from the bottom right and just use the Log / Mocks switch to show and hide the panel:

Take 11. The separation of the mocks and the log

I try switches instead of checkboxes to emphasize that it’s not just a selection, but actually turning things on and off. Also, snuggle the controls to the corners, replace the minus with a trashcan, add a record button for capturing real server responses and using them as mocks later when the server is unavailable:

Take 12

A right-click menu is added to accommodate for some features that do not fit anywhere else.

Switches for mocks look too noisy, and I want to come up with something else. Like a checkbox, but not quite. And here it is, the M symbol:

Take 13

Lots of stuff moves at this point. Log / Mocks switch moves to the left, all toolbars moves to bottom, and two-level tabs hierarchy is flattened. And the Master switch appears in the bottom right corner.

What happens when the user selects a group on the left instead of a mock?

Take 13

What happens when the user selects multiple things?

Take 13

And here is what the log looks like:

Take 13. The design of the full-featured log

Search works like a filter, leaving just the lines matching the query:

Take 13. Searching the log

You may switch between Log and Mocks even when search is active:

Take 13. Searching mocks

It was time to get the status bar and Quick Edit in line with these changes. “Log” and “Mocks” are now always visible on the screen:

Take 13

Request made:

Take 13. The status bar displays the request

Quick Edit:

Take 13

The response timeout setting was here in earlier takes (see Take 6 above), but proved to be not that important for Quick Edit, and so was removed.

To be continued.

Earlier Ctrl + ↓