Рубрики
Без рубрики

Обработка Ajax в вашем реагированном приложении с ловкостью

Есть разные способы обрабатывать AJAX с реагированием. Этот учебник покажет вам несколько способов сделать это. Давайте начнем.

Автор оригинала: Rowland Ekemezie.

Реагировать Экосистема стала огромной, так как Facebook сделала публику API. Более того, отличные библиотеки были построены в декларативном стиле, принятом реагированием.

Однако приложения Real Life требуют создания запросов AJAX на серверы. И это может представлять большую проблему при использовании реагирования. Вам нужно знать, какую библиотеку использовать для ваших процессов AJAX.

Приятно знать, что есть разные способы обрабатывать AJAX с реагированием. Это одна из красавиц реагирования как Просмотр библиотекиГибкость Отказ

Как сделать запрос AJAX с реагированием

  1. В пределах реакции.
  2. Делегата реле.
  3. Делегат redux.

1. В рамках компонента React

Это самый простой и самый распространенный подход для запросов AJAX. Здесь запрос AJAX выпускается непосредственно в ComponentDidmount Способ жизненного цикла вашего компонента. Вещи могут быть запутаны таким образом, когда ваша заявка растет.

Запрос на API GitHub для получения пользовательских деталей выглядит так:

// UserProfile Component
class UserProfile extends React.Component {
  constructor() {
    super();
    this.state = {
      user: []
    }
  }
  // componentDidMount lifecycle method allows dynamic behaviour, AJAX, 
  // side effects, etc. We issue our API call here and set the 
  //  response to component's state.
  componentDidMount() {
    gitHubApi('mentrie').then(data => {
      this.setState({
        user: data
      });
    })
  }

  // Here, we destructure component's state and render the user details.
  render() {
    const { user } = this.state;
    return 

User details

{user.login}

} } // Function that calls our specified endpoint on Github // We're using fetch method from fetch API to make the call. const gitHubApi = (username) => { return fetch(`https://api.github.com/users/${username}`) .then(response => { return response.json() .then(({ login, avatar_url, html_url }) => ({ login, avatar_url, html_url })); }) .catch(error => { throw error; }) }; // We mount the UserProfile component to the DOM ReactDOM.render(, document.getElementById('root'));

Давайте проверим это здесь .

2. Делегационная реле

Реле Позволяет объявить требования к данным для ваших компонентов с GraphQL. И реле делает их доступными через реквизиты.

Реле элегантно для строительства крупных приложений – но у него есть некоторые накладные расходы. Это диапазоны от реле обучения и GraphQL для настройки серверов GraphQL.

Образец релейного потока может посмотреть это:

Источник: Facebook

реагировать js ajax.

3. Делегат Redux.

Redux Создан архитектуру потока для управления состоянием Action Application. С Redux вы перемещаете данные приложения и AJAX процессы от ваших компонентов.

С диаграммы вы можете увидеть, как состояние приложения и асинхронные процессы перемещаются в магазин.

Магазин это объект, который содержит полное состояние вашего приложения. Обратите внимание, что в Redux все состояния приложений хранятся как один объект. Единственный способ изменить его государство – это по Диспетчерские действия Отказ С этой реализацией вы поддерживаете один источник истины по вашему заявлению.

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

Редукторы, учитывая те же аргументы, должны рассчитать следующее состояние и вернуть его. Без сюрпризов. Нет побочных эффектов. Нет вызовов API. Нет мутаций. Редукторы синхронно и пассивные, таким образом, не идеальное место для асинхронизированных действий.

        (previousState, action) => newState

Как тогда вы должны обрабатывать операции с побочными эффектами? Redux Async Библиотеки приходят к спасению:

  1. Redux-обещание
  2. Redux-thunk.
  3. Redux-saga

Они Redux Hamberwares для обработки асинхронных задач и побочных эффектов в вашем приложении React/Redux.

Redux-Promise Использует стандартные действия потока и обещает привлечь четкие конвенции к асинкому вызовам. Это наименее популярное среди трех. Это функция промежуточного программного обеспечения, которая принимает обещание и отправляет разрешенное значение обещания. Он в основном возвращает обещание абоненту, чтобы он мог дождаться операции, чтобы закончить, прежде чем продолжить.

Redux-Thunk позволяет создавать действие для возврата функции вместо объекта действия. Таким образом, Действие Создатель становится Thunk Отказ

А Thunk Это функция, которая создается, часто автоматически, чтобы помочь вызова друшему функции (E.g. API конечной точкой). А Thunk обертывает асинхронную операцию в функции.

Когда Action Creator возвращает функцию, эта функция будет выполняться промежуточным программным обеспечением Thunk Redux. Эта функция не должна быть чистой; Таким образом, ему разрешается иметь побочные эффекты, в том числе выполнение асинхронных вызовов API или переход маршрутизатора. Функция также может отправлять действия.

Чтобы добавить Thunk Redux, мы используем absemiddleware ()

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

Проверьте здесь как Дэн Абрамов Создатель Redux и Redux-Thunk дает подробное объяснение случаев использования.

Мы можем отправить как простые действия объекта, так и другие Teunks, которые позволяют нам составлять асинхронные действия в одном потоке.

// Dependencies
const { applyMiddleware, createStore } = Redux;
const { connect, Provider } = ReactRedux;

// GitHub API
const gitHubApi = (username) => {
   // Put your Api call here
};

// redux-thunk implementation
// source: https://github.com/gaearon/redux-thunk/blob/master/src/index.js
// Redux-thunk handles most use cases for async actions in your application
function thunkMiddleware(store) {
  return function(next) {
    return function(action) {
      if (typeof action === "function") {
        return action(store.dispatch, store.getState);
      } else {
        return next(action);
      }
    }
  }
}

// Action creator
const getUserSuccess = (user) => {
  return {
    type: 'LOAD_USER_SUCCESS',
    user
  }
}

// User reducer implementation.
// Simply returns the new user object to the store on LOAD_USER_SUCCESS.
// Always remember to return state as the default case
const userReducer = (state = {}, action) => {
  switch (action.type) {
    case 'LOAD_USER_SUCCESS':
      return action.user;
    default:
      return state;
  }
};

// fetchUserDetails thunk
// It returns a function that takes dispatch as the first argument. When AJAX 
// request is successful, it dispatches getUserSuccess action with user object.
const fetchUserDetails = (username) => {
  return dispatch => {
   return gitHubApi(username)
      .then(user => {
          dispatch(getUserSuccess(user))
    }).catch(error => { throw error; })
  }
}

// React component
class UserProfile extends React.Component {
  constructor() {
    super();
  }
  
  // We call our thunk here. 
  // componentDidmount is for dynamic behavior, side effects, AJAX, etc.
  componentDidMount() {
    this.props.fetchUserDetails('mentrie');
  }

  render() {
    const { user } = this.props;
      return (
        // Display the user value received from the store
      )
    }
}

// Setup store
const store = createStore(userReducer, applyMiddleware(thunkMiddleware));

// Map the store's state to component's props. 
// This way you keep the component in sync with redux store
const mapStateToProps = (state) =>  ({ 
    user: state 
});

// Wrap the thunk with dispatch method and
// merge them to component's props
const mapDispatchToProps = (dispatch) => ({
    fetchUserDetails: (username) => dispatch(fetchUserDetails(username)) 
});

// Connect React component to redux store with react-redux connect() 
const UserProfilePage = connect(
    mapStateToProps, 
    mapDispatchToProps)(UserProfile);

// Mount the component to the DOM 
// Provider makes available the store's state to component's below 
// the hierarchy via connect() call.
const element = document.getElementById('root');
ReactDOM.render(
  
    
  ,
  element, 0
);

Redux-Thunk легко учиться с относительно небольшим API – всего десять линий кода. Но это может быть трудно проверить.

Давайте проверим это здесь .

Если вам все еще любопытно, см. Другой Async Action пример.

Redux-Saga Это промежуточное программное обеспечение Redux, которая устраняет сложность асинхронных процессов в вашем приложении React/Redux. Он использует силу ES6 Generators Сделать Async Tasks легко проверить, писать и причину.

Redux Saga управляет Async запрос и побочные эффекты более обработанным образом, чем для этого, чем для этого. Это уменьшает сложности в таких просьбах, делая Обратные вызовы, обещания, попробуйте/поймать блокирует только простые инструкции. Более того, это делает ваш код декларативным, более ополнен и читаемым. Тогда как вы могли бы использовать Redux-Thunk и Redux-Saga Вместе сага – это только то, чтобы вылечить ваши сложные боли рабочего процесса.

Когда ваш магазин должен обрабатывать сложные асинхронизированные операции, рассмотрите возможность использования Redux-Saga. Он обрабатывает асинхронные операции как простые инструкции. Redux-Saga элегантно управляет асинхронистыми задачами, сохраняя чистый редуктор.

А. Определите саги

// Here, we use ES6 destructuring assignment to extract payload
// from the action object passed to it.
function* loadUserDetails({ payload }) {
  try {
    const user = yield call(gitHubApi, payload);
    // Yields effect to the reducer specifying action type 
    // and user details.
    yield put({type: 'LOAD_USER_SUCCESS', user}); 
  } catch (error) {
    yield put({ type: 'LOAD_USER_FAILURE', error });
  }
}
// Call loadUserDetails with action's payload each time 
// LOAD_USER_REQUEST is dispatched
function* watchRequest() {
  yield* takeLatest('LOAD_USER_REQUEST', loadUserDetails);
}

Сага являются генераторными функциями. Он использует генератор ES6. Проверьте статью Кайла Симпсона на Основы генератора ES6 Отказ

Генераторы – это функции, которые могут быть приостановлены и возобновлены. Из-за того, как работают генераторы, Redux-Saga способен делать сложные асинхронные рабочие процессы выглядеть синхронно.

У нас есть два сага, чтобы завершить эту операцию: Watchrequest и LoadUserDetails Отказ Сага оформлены на * перед функцией.

API redux-Saga обнаруживает некоторые методы, которые нам нужно для завершения нашей задачи:

  • Позвоните Это создатель эффекта, который запускает функцию с дополнительными параметрами. Он приостанавливает генератор, так как возвращаемый результат – это обещание. Генератор возобновляется, когда обещание разрешено или отклонено.

  • Вилка является создателем эффекта для создания неблокирующих вызовов на функцию.

  • Takelatest Отменяет любую текущую работу и вернуть результат последних действий, которые соответствуют его шаблону.

  • возиться Возвращает результат всех действий, которые соответствует его шаблону.

  • поставить Проще говоря/отправляет действия на указанный канал (объект, используемый для отправки и получения сообщений).

Проверьте Документация Для более методов.

Вернуться к нашему коду

  1. Takelatest Часы для Load_user_request Действия для отправки.
  2. Затем он делает неблокирующий звонок в LoadUserDetails с возвращенным объектом действий. В этом случае тип действия и имени пользователя.
  3. Позвоните управляет Githubapi Функция с полезной нагрузкой (i.e имя пользователя) и разрешает значение, назначенное как Пользователь Отказ
  4. Теперь поставить рассылки Load_user_success С пользовательским значением обратно в магазин.
  5. Наконец, если операция терпит неудачу, хорошая практика для отправки действия отказа, которое в нашем случае является Load_user_failure Отказ

B. Mount Sagas в магазине

// Create saga middleware
const sagaMiddleware = createSagaMiddleware();

// Inject middleware to the store
const store = createStore(userReducer, applyMiddleware(sagaMiddleware));

// Run the sagas you defined. 
// You would normally have a rootSaga were you register all your sagas
// Or spread then in the run function. 
sagaMiddleware.run(watchRequest);

Чтобы сделать состояние и функции магазина доступны для компонента React, React-redux Библиотека предоставляет:

соединить Функция – соединяет реактивный компонент к магазину Redux.

Провайдер Компонент – компонент более высокого порядка, чтобы сделать магазин доступным для всех компонентов ниже иерархии, не передавая его прямо.

C. Подсоедините компонент React React для Store redux

// Dependencies
const { applyMiddleware, createStore } = Redux;
const createSagaMiddleware = ReduxSaga.default;
const { put, call } = ReduxSaga.effects;
const { takeLatest } = ReduxSaga;
const { connect, Provider } = ReactRedux;

// GitHub API
const gitHubApi = (username) => {
  // Make API calls here
};

// Action creator
const getUserDetails = (payload) => {
  return {
    type: 'LOAD_USER_REQUEST',
    payload
  }
}

// Reducer
const userReducer = (state = {}, action) => {
  switch (action.type) {
    case 'LOAD_USER_SUCCESS':
      return action.user;
    default:
      return state;
  }
};

// Sagas goes here

// UserProfile component
class UserProfile extends React.Component {
  constructor() {
    super();
  }

  componentDidMount() {
    this.props.getUserDetails('mentrie');
  }

   render() {
    const { user } = this.props;
    return (
      // Render user details here
   )
  }
}

// Store setup goes here
    - - - - 

// Map the store's state to component's props.
const mapStateToProps = (state) => ({
    user: state
}); 

// Wrap action creator with dispatch method. 
// This way getUserDetails is passed in as props.
const mapDispatchToProps = (dispatch) => ({ 
    getUserDetails: (username) => dispatch(getUserDetails(username))
}) 

// React-redux connect function links our React component to redux store
const UserProfilePage = connect(
    mapStateToProps,
    mapDispatchToProps)(UserProfile);

// Mount our component to the DOM
const element = document.getElementById('root');
ReactDOM.render(
  
    
  ,
  element, 0
);

Давайте проверим это здесь .

Обертывание

Операции AJAX в вашем приложении React лучше обрабатываются с библиотеками redux async. При использовании Redux, Не кладите AJAX в свои комментарии реагирования. Отделение беспокойства является ключом. Более того, если ваше приложение React/Redux требует совершения Async-операций, используйте Redux-Thunk или Redux-Saga, чтобы справиться с ней с Agility и элегантностью. Создание ASYNC запросов в ваших редукторах является анти-образцом и следует избегать.