SharePoint Framework - Fetching Data In React

Overview

ReactJS is commonly used to develop solutions in SharePoint Framework. It is a common practice to fetch the data from SharePoint site, Office 365, MS Graph API, or from any external service and display it in SharePoint Framework Web Part. However, there is always a confusion about which React method is the best place to fetch the data.

In this article, we will explore all possible options to fetch data from React components and the pros and cons of each option.

Render Method of React Component

Each React component has a Render method. The obvious thought is to have fa etch mechanism inside the Render method. However, it is not a good place to fetch the data, the reason being, that it causes a state change. Also, it is not advisable to perform any asynchronous calling in Render method.

The commonly used options are componentWillMount and componentDidMount.

componentWillMount

This method is called right before React component’s first render occurrence. Just by reading this statement, it is tempting to have the fetching mechanism inside componentWillMount. But wait! This place might not be ideal for fetching the data as asynchronous calls to fetch the data might not return before the Render method executes. This means, there is a high chances that the component will render empty data at least once.

We also cannot pause the Render method until componentWillMount finishes, nor can we return a promise from componentWillMount. To handle this situation gracefully, we can set up the component's initial state.

Let us take an example of fetching the data from service.

class Employee extends Component {  
  componentWillMount() {  
    dataService.get('/mydata').then(result => {  
      this.setState({items: result.data});  
    });  
  }  
  
  render() {  
    return (  
      <ul>  
        {this.state.items.map(item =>  
          <li key={item.id}>{item.name}</li>  
        )}  
      </ul>  
    );  
  }  
}

In this example, componentWillMount is calling the dataService asynchronously which will result in empty data on the first occurrence.

To handle this situation, we can set the initial state in the constructor

constructor(props) {  
    super(props);  
  
     this.state = {  
        items: []  
    };  
} 

We can also check for empty data in the Render method.

render() {  
  return (  
    <ul>  
      {this.state && this.state.items && this.state.items.map(item =>  
        <li key={item.id}>{item.name}</li>  
      )}  
    </ul>  
  );  
}

componentWillMount is now deprecated, so it is not good idea to still keep using this method. 

componentDidMount

React component gets rendered once before calling componentDidMount. It is ideal to use this method to fetch the data for the below reasons,

  1. Data will not be loaded until after initial render. This will make it compulsory to setup the initial state to avoid undefined state errors.
  2. In case the app needs server rendering, componentWillMount will get called twice (one time on server and on client). Having a data fetching mechanism in componentDidMount will ensure that data is fetched only once on client.

componentDidMount will always be called on client after first render when it has received the data. Try to avoid any kind of state change in componentDidMount, because it will cause re-rendering of the component, which in turn will call componentDidMount which will again call Render method and so on and on. This will cause an infinite loop.

componentDidMount can be used to setup long running processes that can fetch data from SharePoint or any external service on a periodic basis.  

componentDidMount() {  
  this.interval = setInterval(this.fetchMyDaya, 3600000);  
}

Summary

While developing SharePoint Framework webpart with React, it is recommended to use componentDidMount over any other place. Try to avoid using componentWillMount as it is deprecated. Render method is not a good place for fetching the data as it causes the state change.