Как обрабатывать побочные эффекты при переходе с Redux на React Context API хуки

#reactjs #react-context

#reactjs #реагировать-контекст

Вопрос:

Если у вас есть приложение Redux, которое вы хотели бы перенести на новый React Context API хуки (useReducer), как бы вы заменили redux-saga или redux-thunk для обработки побочных эффектов? Давайте возьмем пример со страницы redux-saga на github:

 import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'

function* fetchUser(action) {
   try {
      const user = yield call(Api.fetchUser, action.payload.userId);
      yield put({type: "USER_FETCH_SUCCEEDED", user: user});
   } catch (e) {
      yield put({type: "USER_FETCH_FAILED", message: e.message});
   }
}

function* mySaga() {
  yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}

function* mySaga() {
  yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}

export default mySaga;
  

Какова рекомендуемая наилучшая практика для выполнения эквивалента без Redux, но с использованием вместо этого React Context api хуки?

Комментарии:

1. вы можете использовать обычный метод, такой как fetch или axios, для обработки синхронизации и асинхронного запроса в приложении без redux.

2. Наилучшей практики нет, пользовательский интерфейс прост. Побочные эффекты, скорее всего, произойдут в useEffect, если только вы не придумаете какую-нибудь надстройку, похожую на Saga.

Ответ №1:

Взгляните на useEffect перехват. Это то, что вы используете для побочных эффектов.

https://reactjs.org/docs/hooks-effect.html

Вот пример того, как вызвать API из вашего компонента и отобразить данные:

 import ReactDOM from "react-dom";
import React, { useState, useEffect } from "react";
import axios from "axios";

function SearchResults() {
  const [data, setData] = useState(null);
  useEffect(() => {
    function getFetchUrl() {
      return "https://hn.algolia.com/api/v1/search?query=react";
    }
    async function fetchData() {
      console.log("asdasd");
      const result = await axios(getFetchUrl());
      setData(result.data);
    }

    fetchData();
  }, []);
  return <div>{JSON.stringify(data)}</div>;
}

ReactDOM.render(<SearchResults />, document.getElementById("root"));
  

Я частично взял этот код из overreacted.io Я настоятельно рекомендую вам прочитать эту удивительную статью о useEffect хуке:https://overreacted.io/a-complete-guide-to-useeffect /

Что касается useReducer , это в основном useState на стероидах. Это позволяет обрабатывать более сложные операции с состоянием, но на самом деле большой разницы нет.

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

—- о redux:

Я просто хочу также прокомментировать, что переход на использование React Context api хуки для замены redux в вашем приложении может быть полезным, если вы просто используете его для передачи данных, например, во вложенные компоненты. Но если вам нужны все отличные инструменты, промежуточное программное обеспечение, инструменты разработки и т.д., Redux по-прежнему является отличным выбором, даже с хуками, они не являются взаимоисключающими.

Смотрите:

https://blog.isquaredsoftware.com/2019/03/presentation-state-of-redux/ В частности https://blog.isquaredsoftware.com/presentations/2019-03-state-of-redux/#/10
https://blog.isquaredsoftware.com/presentations/2019-03-state-of-redux/#/11

Комментарии:

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

Ответ №2:

Если у вас есть приложение Redux, которое вы хотели бы перенести на новый React Context API, вам нужно иметь возможность получать данные для любого компонента в вашей иерархии, вам нужно иметь возможность отделять логику представления от бизнес-логики, и вам нужно иметь возможность разделять бизнес-логику, что означает модульность, то есть не иметь 1000 LOCS в одном файле.

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

С Context вам не нужно использовать отдельную библиотеку, вот и все. Это единственное преимущество использования Context вместо Redux. Контекст имеет свои собственные проблемы из-за сквозных проблем при создании хранилища.