Lukon
Lukon

Reputation: 265

Determining when to use a container in React. RE: fetching data from API and common practices

From what I'm gathering from the community and the React docs, there seems to be a consensus that components should always aim to be stateless. Given this idea, I'm having a difficult time implementing this methodology in a way that that feels correct.

The overall goal is this: have a container component that uses Axios to make an http request to an API. This data set will then become the components state, and be passed to a child component(s) that builds a table with said data. I'm rather new to React, but this is how I'm approaching the issue:

I have a DeploymentsContainer.js that I think should be responsible for getting the data:

import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';

class FetchDeployments extends React.Component {
constructor(props) {
    super(props);

    this.state = {
        deployments: []
    };
}

componentDidMount() {
    axios.get(`API ENDPOINT`)
        .then(res => {
            // Store response data in array
            const fetchedData = res.data._deployments;
        });
}

render() {
    return (
        <div>

        </div>
    )
}
}

export default FetchDeployments;

Next, I have a Deployments.js component that is going to serve as the actual view for a combination of components:

import React from 'react';
import TopBar from '../TopBar/TopBar';
import DeploymentsHeader from '../DeploymentsHeader/DeploymentsHeader';
import DeploymentsToolbar from '../DeploymentsToolbar/DeploymentsToolbar';
import FetchDeployments from '../../../containers/DeploymentsContainer/DeploymentsContainer';
import DataTable from '../DataTable/DataTable';

import './Deployments.css';

const Deployments = () => (
    <div className="">
        <TopBar />
        <DeploymentsHeader />
        <DeploymentsToolbar />
        <FetchDeployments />
        <DataTable />
    </div>
);

export default Deployments;

This is where I'm struggling. I'm new to React and this type of framework, so I'm doing my best to not make this a stupid question and start a subjective debate. But, if my overall goal is to store the data in a table using an external React Data Table Library, is it appropriate to break up the container into a separate thing, then I guess pass the data to the library when it gets mounted? I'm really not sure if I'm understanding the separation of state and what not here. Do I even need a container?

How does a separate component access the data from a container that are both being mounted at the same time?

Upvotes: 0

Views: 228

Answers (1)

John
John

Reputation: 2894

As always, the answer is 'it depends'. The best you can do as you are learning React and its ecosystem is start to learn the various tradeoffs that you make as you adopt various approaches. The idea of using HoC's (higher order components) to separate presentational components versus container components is a popular one, and worth exploring. Often it is an idea used along with a separate state management solution, whether that be something like redux, mobx, graphql, or even something like recompose's withState. There is nothing stopping you from implementing the same approach along with React's setState api. It may be worth trying as a learning exercise, but I personally have mostly just used HoC's when combined with one of the libraries I mentioned above.

To speak to your questions more directly:

Is it appropriate to break up the container into a separate thing, then I guess pass the data to the library when it gets mounted? I'm really not sure if I'm understanding the separation of state and what not here. Do I even need a container?

I would personally only move to container components if I were going to move beyond React's setState api.

The nice thing about setState is the simplicity, and as the creator of Redux points out sometimes simple is best. It is more important as your app scales to have a scalable way of dealing with state, so it's mostly going to be your decision as to where to draw the line.

In my experience, this will be as soon as you grow your app to having multiple levels of component hierarchy. By then you will often find yourself with several levels of separation between where state lives and where it is used. This leads to passing data through multiple levels of components to funnel it through to where it needs to be, which of course gets tedious and also couples each component along the way. This is where extracting state out and being able to access it through a container component really starts to shine.

How does a separate component access the data from a container that are both being mounted at the same time?

In React, a parent will be mounted before a child. So your container would be mounted first, and would be given an opportunity to prepare data to pass to the child to be mounted with. Of course what can often happen is your container might initiate some asynchronous action (such as an API request), so it may not have the data the child needs. In this case, the child may want to conditionally render based on whether the data has arrived.

Hopefully this helps!

Upvotes: 2

Related Questions