Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I call APIs in componentWillMount in React?

Tags:

I'm working on react for last 1 year. The convention which we follow is make an API call in componentDidMount, fetch the data and setState after the data has come. This will ensure that the component has mounted and setting state will cause a re-render the component but I want to know why we can't setState in componentWillMount or constructor

The official documentation says that :

componentWillMount() is invoked immediately before mounting occurs. It is called before render(), therefore setting state in this method will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method.

it says setting state in this method will not trigger a re-rendering, which I don't want while making an API call. If I'm able to get the data and able to set in the state (assuming API calls are really fast) in componentWillMount or in constructor and data is present in the first render, why would I want a re-render at all?

and if the API call is slow, then setState will be async and componentWillMount has already returned then I'll be able to setState and a re-render should occur.

As a whole, I'm pretty much confused why we shouldn't make API calls in constructor or componentWillMount. Can somebody really help me understand how react works in such case?

like image 940
Ajay Gaur Avatar asked Apr 01 '17 08:04

Ajay Gaur


People also ask

Can I call API in componentWillMount?

Using componentWillMount() to Make API Calls One of the primary usages of componentWillMount() is to make API calls once the component is initiated and configure the values into the state. To make an API call, use an HttpClient such as Axios , or or you can use fetch() to trigger the AJAX call.

Why do we make API calls in componentWillMount functions?

Calling API in constructor() or componentWillMount() is not a syntax error but increases code complexity and hampers performance. So, to avoid unnecessary re-rendering and code complexity, it's better to call API after render(), i.e componentDidMount().

Can I call API in React constructor?

As best place and practice for external API calls is React Lifecycle method componentDidMount(), where after the execution of the API call you should update the local state to be triggered new render() method call, then the changes in the updated local state will be applied on the component view.


2 Answers

1. componentWillMount and re-rendering

Compare this two componentWillMount methods.
One causes additional re-render, one does not

componentWillMount () {   // This will not cause additional re-render   this.setState({ name: 'Andrej '}); }  componentWillMount () {   fetch('http://whatever/profile').then(() => {     // This in the other hand will cause additional rerender,     // since fetch is async and state is set after request completes.     this.setState({ name: 'Andrej '});   }) } 

.
.
.
2. Where to invoke API calls?

componentWillMount () {   // Is triggered on server and on client as well.   // Server won't wait for completion though, nor will be able to trigger re-render   // for client.   fetch('...') }  componentDidMount () {   // Is triggered on client, but never on server.   // This is a good place to invoke API calls.   fetch('...') }  

If you are rendering on server and your component does need data for rendering, you should fetch (and wait for completion) outside of component and pass data thru props and render component to string afterwards.

like image 146
Andreyco Avatar answered Dec 22 '22 01:12

Andreyco


ComponentWillMount

Now that the props and state are set, we finally enter the realm of Life Cycle methods

That means React expects state to be available as render function will be called next and code can break if any mentioned state variable is missing which may occur in case of ajax.


Constructor

This is the place where you define.

So Calling an ajax will not update the values of any state as ajax is async and constructor will not wait for response. Ideally, you should use constructor to set default/initial values.


Ideally these functions should be pure function, only depending on parameters. Bringing ajax brings side effect to function.

Yes, functions depend on state and using this.setState can bring you such issues (You have set value in state but value is missing in state in next called function).

This makes code fragile. If your API is really fast, you can pass this value as an argument and in your component, check if this arg is available. If yes, initialise you state with it. If not, set it to default. Also, in success function of ajax, you can check for ref of this component. If it exist, component is rendered and you can call its state using setState or any setter(preferred) function.

Also remember, when you say API calls are really fast, your server and processing may be at optimum speed, but you can never be sure with network.

like image 30
Rajesh Avatar answered Dec 22 '22 00:12

Rajesh