Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I put AJAX calls in the presentational component, or should I extract a container?

I spend a lot of time thinking about how to best structure things as cleanly as possible in React. Lately I've been getting hung up on whether React containers should do nothing but connect to Redux (or other data - a la Meteor) and render/return a single component, or if containers should also be in charge of event-handling as well. So for example, it's a toss-up between these two models:

Model 1

// ThingContainer.js

import Thing from '../components/Thing';
export default someHigherOrderFunc(/* map state/data to props */)(Thing)

// Thing.js

export default class Thing extends Component {
  handleClick() { /* ... */ }
  handleMouseEnter() { /* ... */ }
  render() {
    // Other components rendered here, both container or presentational
  }
}

Model 2

// ThingContainer.js

class ThingContainer extends Component {
  handleClick() { /* ... */ }
  handleMouseEnter() { /* ... */ }
  render() {
    // Now Thing can be stateless
    return <Thing 
      onClick={this.handleClick}
      onMouseEnter={this.handleMouseEnter}
    />
  }
}

export default someHigherOrderFunc()(ThingContainer)

It almost feels like in model 1, Thing becomes its own container in a sense, which I'm not sure I like. Model 2 feels more natural, as ThingContainer is charged with not just dealing with data and Redux, but also handling events, firing off Ajax requests in componentDidMount, etc. With the first model, if I wanted an Ajax request to be invoked in componentDidMount, it would have to go in Thing which doesn't seem right.

I'm wondering if there are any particular advantages or pitfalls to either of these approaches, or if it just comes down to style/preference.

like image 289
ffxsam Avatar asked Mar 30 '16 18:03

ffxsam


People also ask

Where can you initiate your AJAX requests?

In this method, we initiate the AJAX request using XMLHttpRequest . We use the GET method and https://programming-quotes-api.herokuapp.com/quotes/page/1 as the endpoint which returns a JSON output of first page quotes. readystatechange handler is called when the readyState of the request changes.

Where in a React component should you make an Ajax?

Where in the component lifecycle should I make an AJAX call? You should populate data with AJAX calls in the componentDidMount lifecycle method. This is so you can use setState to update your component when the data is retrieved.

How can you implement the container components in React?

Here's an example below: import React from “react” export const exampleComponent = ({ children }) => { const open = () => { alert("You clicked this container component") } return ( <div onClick={open}> {children} </div> ); };


1 Answers

There is nothing inherently wrong with doing AJAX inside the “presentational-ish” Thing when it’s only a couple of methods, and this component is never used in different scenarios anyway. Don’t split behavior from presentation before you’re sure how the behavior changes in different contexts.

That you have this dilemma means your component doesn’t need to be reused yet. In this case it doesn’t matter how you split it. Both ways work fine so I’d go for the simpler one (model 1).

Later you may realize that you want to reuse the same look-n-feel but trigger different AJAX calls, or compute the props differently. At this point you may want to remove the event handling from Thing and create several different ThingContainers, each handling events and computing props a little bit differently. This is when separating presentation and behavior becomes useful.

like image 81
Dan Abramov Avatar answered Oct 01 '22 17:10

Dan Abramov