简体   繁体   中英

Is it best to perform an API call on componentDidMount or componentWillMount?

I am trying to figure out what is the best way to perform an api call. I need to get the data when the component loads and not on any onClick/onPress method. This is the api call using fetch:

import { Alert, AsyncStorage } from 'react-native';
import { has } from 'lodash';
import PropTypes from 'prop-types';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { passengersDataAction } from '../screens/HomeScreen/actions/homeScreen';

const GetPassengersData = async (
  username,
  password,
  navigation,
  passengersDataActionHandler,
) => {
  try {
    const response = await fetch(
      'http://myAPI/public/api/getPassengers',
      {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${868969}`,
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email: username, password }),
      },
    );
    const responseJson = await response.json();
    if (has(responseJson, 'error')) {
      Alert.alert('Error', 'Please check your credentials.');
    } else {
      await AsyncStorage.setItem('userToken', responseJson.success.token);
      passengersDataActionHandler(responseJson.success.token);
      navigation.navigate('App');
    }
  } catch (error) {
    Alert.alert(
      'Error',
      'There was an error with your request, please try again later.',
    );
  }
};

GetPassengersData.propTypes = {
  navigation: PropTypes.shape({}).isRequired,
  passengersDataActionHandler: PropTypes.func.isRequired,
};

export default compose(
  connect(
    store => ({
      userToken: store.signinScreen.userToken,
      passengersData: store.homeScreen.passengersData,
    }),
    dispatch => ({
      passengersDataActionHandler: token => {
        dispatch(passengersDataAction(token));
      },
    }),
  ),
)(GetPassengersData);

The call will be perform here:

class AllPassengers extends Component {
  compo
  render() {
    return (
      <ScrollView>
        <View style={{ height: 50 }} />
        <View
          style={[
            tabViewStyles.container,
            { alignItems: 'center', justifyContent: 'center' },
          ]}
        >
          <Text style={{ fontWeight: 'bold' }}>
            Select passengers to start your route
          </Text>
          <View style={{ height: 50 }} />
          <PassengersCircle />
        </View>
        <AllPassengersList />
      </ScrollView>
    );
  }
}

export default AllPassengers;

And I was also wondering if there is a way to make that call on an functional/stateless component?

componentWillMount() is invoked just before mounting occurs. It is called right before render(), so by the time you get the data, the render() has already been called, your component should be able to render without any data.

It's recommended on the React Docs to fetch the data in componentDidMount() .

Avoid introducing any side-effects or subscriptions in this method. For those use cases, use componentDidMount() instead.

componentWillMount will be marked as “legacy”. it still works, but not recommended.

Note

This lifecycle was previously named componentWillMount. That name will continue to work until version 17. Use the rename-unsafe-lifecycles codemod to automatically update your components.

check this to see how to fetch data in a functional component .

Snippet from the link above :

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = useState({ hits: [] });

  useEffect(async () => {
    const result = await axios(
      'http://hn.algolia.com/api/v1/search?query=redux',
    );

    setData(result.data);
  });

  return (
    <ul>
      {data.hits.map(item => (
        <li key={item.objectID}>
          <a href={item.url}>{item.title}</a>
        </li>
      ))}
    </ul>
  );
}

export default App;

componentWillMount has been considered "legacy" since React 16.3 and had "UNSAFE" prepended to the function name to make that point clear: https://reactjs.org/docs/react-component.html#unsafe_componentwillmount and it will be removed altogether in an upcoming release of React (17.0). You can read more about this in the React blog but the key quote is probably:

[componentWillMount] is problematic for both server rendering (where the external data won't be used) and the upcoming async rendering mode (where the request might be initiated multiple times).

Therefore to keep your component working you should perform data fetching in componentDidMount .

To do this in a functional component, you may be able to use the new React feature of " Hooks ". This enables the use of some state-mutating features of class components in functional components.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM