Проблемы с попыткой вернуть данные api без класса

Я построил api, который возвращает мне единицы, которые я зарегистрировал в БД, но при попытке вернуть их не просматривают

import React, { Component } from 'react';
import axios from 'axios';

const api = {

  units: () => {
    axios.get('http://192.168.0.23/api/public/api/units')
    .then(response => {
      console.log(response);
        return response.data.data
    }).catch((error) => { 
      console.log(error.message)
    });
    return 'Error'
  },

};

export default api;

Ответ отображает данные правильно, response.data.data, если он используется в файле с классом I, можно установить состояние units = [] и с setState вернуть единицы

Однако я хотел бы создать этот файл для возвратов api, однако, поскольку я не использую класс, поэтому понимаю, что я не могу использовать состояние.

Есть ли способ без класса, возвращающего эти данные, или сохранения в переменной или что-то в этом роде?

Или используйте setState прямо здесь без класса?

Я считаю, что это будут способы решения моей проблемы, но если кто-то другой знает иначе, чем положить api-вызов в тот же файл, что и последний класс.

Я тоже пробовал:

async function getUnits() {   
  return await axios.get('http://192.168.0.23/api/public/api/units');
}

getUnits.then((response) => {
  console.log(response);
    return response.data.data
}).catch((response) => { 
  console.log(response)
});

Но ошибка показала, что getUnits.then is not a function

Даже с нормальной функцией не работает:

function units() {
  axios.get('http://192.168.0.23/api/public/api/units')
  .then(response => {
    console.log(response);
      return response.data.data
  }).catch((error) => { 
    console.log(error.message)
  });
  return 'Error'
};

Ответ 1

Используйте следующий код, это поможет вам.

Обычно мы просто загружаем данные, а затем выводим наше приложение. Но React ожидает некоторого начального состояния для всех этих данных и нуждается в обновлении сразу после завершения запроса AJAX. По этой причине вам нужно сохранить все эти данные в состоянии приложения.

Вот как это выглядит:

      import React, { Component } from 'react';
      import { Platform, StyleSheet, Text, View } from 'react-native';
      import axios from 'axios';


      export default class App extends Component { 

        constructor(props) {
          super(props);

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

        componentDidMount() {
          this.getUnits();
        }

        getUnits() {
          axios.get('http://192.168.0.23/api/public/api/units')
          .then(response => {
            this.setState({ units: response.data.data }));
          }).catch((error) => { 
            console.log(error.message)
          });
        }

        render() {
          const unit = this.state.units.map((item, i) => (
            <div>
              <h1>{ item.example }</h1>
            </div>
          ));

          return (
            <View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center' }}>
              <Text>Units: {unit}</Text>
            </View>
          );
        }
      }

И если вы хотите, чтобы субкомпоненты передавали эти данные до. Вот что это выглядит:

          const unit = this.state.units.map((item, i) => (
            <div>
              <h1>{ item.example }</h1>
             <Test unitData={item} />
            </div>
          ));

В другом компоненте Test

        class Test extends Component { //use the data in a class component

          constructor(props) {
            super(props);
          }

          render() {
            const unit = this.props.unitData

            return (
              <div className="test">
               <h1>{unit.example}</h1>
              </div>
            );
          }
        }

Пожалуйста, посмотрите пример здесь, который поможет вам решить вашу проблему.

Примеры:

Надеюсь, это поможет вам!

Ответ 2

Сначала в этом фрагменте

async function getUnits() {   
  return await axios.get('http://192.168.0.23/api/public/api/units');
}

getUnits.then((response) => {
  console.log(response);
    return response.data.data
}).catch((response) => { 
  console.log(response)
});

Вы допустили ошибку, вы должны вызвать функцию getUnits здесь, например:

getUnits().then(.....)

Относительно того, использовать или не использовать компонент с состоянием или функциональный компонент, просмотрите документацию здесь для некоторого объяснения различий.

На первой странице обсуждаются функциональные компоненты, которые не управляют своим собственным состоянием. вторая страница обсуждает состояние.

В вашей ситуации один из компонентов должен будет выполнить вызов AJAX, поэтому один компонент должен отвечать за состояние. Если вы используете Redux, разговор становится совсем другим. Однако, если вы не используете Redux, вы, как правило, будете иметь состояние в компоненте с высоким уровнем состояния с компонентами без состояния под ним. Базовый компонент передаст данные (из вашего запроса AJAX) своим детям без гражданства с помощью реквизита (которые доступны только для чтения).

Итак, наконец, мы сможем получить код! В вашем объекте api позвольте поддерживать способ передачи данных обратно вызывающему абоненту. Здесь мы добавляем параметры обратного вызова onLoad и onError, которые принимают функции как аргументы. Когда приходит успешный ответ, обратный вызов onLoad вызывается с данными из API. При возникновении ошибки обратный вызов onError вызывается с сообщением об ошибке.

import axios from 'axios';

const api = {
  units: (onLoad, onError) => {
    axios.get('http://192.168.0.23/api/public/api/units')
    .then(response => {
        onLoad(response.data.data);
    }).catch((error) => { 
        onError(error.message);
    });
  },
};

export default api;

Теперь мы сделаем ваш компонент App stateful (помните, он может иметь детей без гражданства, чтобы он передавал данные через реквизит). Обратите внимание, что мы вызываем вызов API прямо перед тем, как компонент будет монтироваться, потому что мы вызываем его в componentWillMount метод жизненного цикла React. Это не помешает рендерингу компонента, поскольку, поскольку ваш объект api выполняет асинхронный вызов, он просто вызывает запрос API и немедленно отображает ваш компонент. Как только данные поступят, ваш объект api вызовет обратный вызов onLoad, который является методом onApiLoad вашего компонента App. Компонент App затем обновит свое состояние и повторную визуализацию!

import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import api from './units';

export default class App extends Component {

  constructor(props) {
    super(props);

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

  componentWillMount() {
    api.units(this.onApiLoad, this.onApiError);
  }

  onApiLoad(units) {
    this.setState({
      units: units
    });
  }

  onApiError(errorMessage) {
    // TODO Something meaningful with error message
  }

  render() {
    const unit = this.state.units.map((item, i) => (
      <div>
        <h1>{ item.example }</h1>
      </div>
    ));

    return (
      <View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Units: {unit}</Text>
      </View>
    );
  }
}

Ответ 3

Если у меня возникла ваша проблема, то это то, что вам нужно сделать:

измените это:

import React, { Component } from 'react';
import axios from 'axios';

const api = {

units: () => {
  axios.get('http://192.168.0.23/api/public/api/units')
    .then(response => {
      console.log(response);
      return response.data.data
    }).catch((error) => {
    console.log(error.message)
  });
  return 'Error'
},

};

export default api;

в

import axios from 'axios';

const api = {

units: () => {
  return axios.get('http://192.168.0.23/api/public/api/units')
    .then(response => {
      console.log(response);
      return response.data.data
    }).catch((error) => {
    console.log(error.message)
  });
  return 'Error'
},

};

export default api;

просто добавил оператор возврата перед axios

затем используйте его в своем компоненте, например

import api from './api';
....
....
....
componentDidMount() {
  api.units().then(units => this.setState({ units }))
}
....
....
....

Ответ 4

Я столкнулся с этой проблемой асинхронного обратного вызова в мои первые дни программирования с помощью javascript, где мне было очень сложно передавать результаты между файлами с использованием чистых функций. Я могу предложить вам что-то, что вы можете использовать в любом месте с асинхронным программированием в javascript и не имеет никакого отношения к response.js

import React, { Component } from 'react';
import axios from 'axios';

const api = {

  units: (callback) => {
    axios.get('http://192.168.0.23/api/public/api/units')
    .then(response => {
      console.log(response);
        callback(response.data.data);
    }).catch((error) => { 
      console.log(error.message)
    });
    return 'Error'
  },

};

export default api;

И внутри вашего компонента App:

import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';

import api from './units';

export default class App extends Component { 
  constructor(props) {
    super(props);

    this.state = {
      units: [],
    };
  }
  //Always do async tasks(side effects) in componentDidMount, I will provide you a link to know Do and Dont with lifecycle hooks.

  componentDidMount() {
    if(this.state.units.length === 0){
      api.units((data) => this.setState({units: data}));
    }
  }

  render() {
    return (
      <View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Units: {this.state.units}</Text>
      </View>
    );
  }
}

Это способ передачи функций обратного вызова, когда вы работаете с асинхронными операциями в Javascript, так как вы не можете вернуть результат evaluated из функции async, потому что, как только результат все еще будет оцениваться, ваша функция будет return что-то и выйти из scope, но вы можете использовать обработчик callback операции async, чтобы, наконец, обновить ваше представление в соответствии с оцененным result. Я обрабатываю только обратный вызов success, вы можете передать обратный вызов error, чтобы обработать случай ошибки.