Hacker News new | ask | show | jobs
by biscarch 3537 days ago
Loading (and error, etc) state should be the responsibility of the component doing the content rendering, not the parent. So the ConditionalSpinner component:

   <ConditionalSpinner renderIf={data}><PersonRenderer person={data.person} /></ConditionalSpinner>
Could be written better as:

   <PersonRenderer person={data.person} />
Where PersonRenderer would be defined as such:

   class PersonRenderer extends Component {
     render() {
       if(this.props.person) {
         return <div>personcontent</div>
       }
       return <LoadingIndicator/>
     }
   }
Given this, I'm still not sure how an If "component" would be achieved (and further, you'd need an Else or a Switch component anyway if going down this route). Maybe you could explain the benefits of such a path?
2 comments

or create a wrapper function ...

  function withLoadingIndicator(Wrapped) {
    return function(props) {
      if (props.loading) {
        return (<LoadingIndicator />);
      }
      return (<Wrapped {...props} />);
    }
  }

  // ...

  export class PersonRenderer extends Component {
    render() {
      return <div>personcontent</div>
    }
  }

  export default withLoadingIndicator(PersonRenderer);
I first learned about this method with react-dnd and have used it extensively since. Quite elegant.
> Loading (and error, etc) state should be the responsibility of the component doing the content rendering

It's often divided in two: One container fetching the data, and a pure component rendering it.

I think my intent might have come across wrong here.

The "states" aren't related to container/dumb components or data-fetching/selection logic. They're purely about rendering the state for a given segment of the page. Perhaps this article[0] might help convey my intent. It's more about how to render "we didn't get data from that one endpoint for this section of the page" or "we're waiting for the data to show up", etc.

[0]: https://medium.com/swlh/the-nine-states-of-design-5bfe9b3d6d...