React Js - объединить уровни Redux и Services - PullRequest
0 голосов
/ 14 марта 2019

После некоторых исследований я нашел несколько вопросов о стековом потоке относительно того, чего я пытаюсь достичь, однако я не чувствую, что эти вопросы и их ответы дают мне «ответы» или «указания», которые я ищу. .

Примечание : Я довольно новичок, чтобы реагировать, даже если я уже сделал 2 проекта и внедрил Redux в один из них. Тем не менее, я совсем не новичок в C # или Go, тем более в C. На основании своего опыта я просто привык к некоторым архитектурам и хотел бы воспроизвести одну из них.

Вот хорошая схема из подобного моего вопроса:

enter image description here

Ситуация:

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

Моя идея об этом - использовать службу MapService.js. Этот будет просто хранить обнаруженные фрагменты карты и автоматически запрашивать у сервера новые, и, конечно, сохранять новые (concat).

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


Исходя из того, что я сказал, у нас будет что-то вроде:

Страница -> Компонент -> Сервис -> API

Исходя из этого, мой API получит ответ API, обработает его и вернет компоненту. Обработано означает (данные добавлены к предыдущему, затем все возвращено)


Я видел в Интернете один вопрос, который ссылался на шаблон «MVCS» (Model View Controller Service), и мне кажется, что я что-то ищу, но не уверен, как реализовать это в ReactJ.

Redux - это то, что вы вкладываете в свое решение повсюду. Я хотел бы использовать его в качестве «хранилища», скажем так, чтобы иметь возможность управлять им из службы, а не из самого компонента. Однако служба должна быть единым экземпляром, совместно используемым в приложении, и я не знаю, может ли такое решение, как внедрение зависимостей, быть решением в ReactJS

Не стесняйтесь просить любые изменения, если вам нужно больше деталей:)

Спасибо за вашу помощь!

Ответы [ 2 ]

2 голосов
/ 14 марта 2019

Этот файл будет просто хранить обнаруженные фрагменты карты и автоматически спрашивать сервер о новых, и, конечно, сохранять новые

Это то, что яМы хотели сделать в прошлом, но никогда не реализовывали решение для.

Проблема в том, что вы, по сути, хотите «пересечь потоки» ..

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

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

Подумав об этом сейчас, мне интересно, есть ли способ сделать это без добавления логики вваш компонент представления должен обернуть его в компонент ( HOC ), который обеспечивает логику.

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

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

непроверенный дамп памяти ниже

загрузчик HOC:

import React, { useEffect } from "react";
import actions from "./actions";

function withLocationLoader(Component) {
  const Wrapper = function ({ location, locations, loadLocation, ...props }) {
    useEffect(() => {
      if (!locations[location]) {
        loadLocation(location);
      }
    }, [locations]);

    if (locations[location]) {
      return <Component locations={locations} {...props} />;
    }
    return <div>Loading...</div>;
  }

  const mapStateToProps = (state, ownProps) => {
    return { locations: state.locations };
  };

  const mapActionsToProps = {
    loadLocation: actions.loadLocation,
  };

  return connect(
    mapStateToProps,
    mapActionsToProps
  )(Wrapper);
}

export { withLoader };

компонент:

function MyBareComponent({ locations }) {
  return <div>{JSON.stringify(locations)}</div>;
}

const MyComponent = withLocationLoader(MyBareComponent);

export { MyComponent };

действия: (с использованием промежуточного программного обеспечения redux-thunk)

function setLocation(location, data) {
  return { type: "SET_LOCATION", payload: { location, data } };
}

export function loadLocation(location) {
  return dispatch =>
    Promise.resolve({ geoData: "" }) // mock api request
      .then(data => dispatch(setLocation(location, data)));
}
2 голосов
/ 14 марта 2019

Вот минимальный пример использования промежуточного программного обеспечения Redux.Обычно разработчики Redux используют библиотеки (которые предоставляют вам промежуточное ПО) для доступа к более подходящим API.

Промежуточное ПО Redux объединено в цепочку, поэтому каждое промежуточное ПО может вызывать следующее промежуточное ПО.Первое промежуточное программное обеспечение цепочки вызывается каждый раз, когда вызывается функция dispatch (вы можете получить ее через response-redux connect).В промежуточном программном обеспечении, если следующего промежуточного программного обеспечения нет, будут вызываться редукторы.Следующее промежуточное программное обеспечение может вызываться асинхронно после получения действия.(Документы Redux все равно будут лучше моих объяснений).

В моем примере есть catService, который предоставляет функцию, которая вызывает rest API.Ваши услуги могут быть чем угодно (например, экземпляром класса или синглтоном).Обычно в стеке React / Redux разработчики не используют объектно-ориентированную разработку.

Если компонент отправляет getCat(123), будет вызываться catMiddleware (синхронно).Тогда requestGetCat будет вызван с идентификатором 123.Когда обещание, возвращаемое requestGetCat, будет разрешено, через редукторы будет отправлено действие setCat для обновления состояния избыточности.Как только состояние избыточности будет завершено, компонент, прослушивающий объект cat items, также будет обновлен (вызывая повторное отображение).

Это может выглядеть очень сложным, но на самом деле это очень масштабируемый и удобный.

// catService.js

// return a promise that return a cat object
const requestGetCat = id =>
    fetch(`www.catcat.com/api/cat/${id}`)
        .then(response => response.json())

// catTypes.js

export const GET_CAT = 'GET_CAT'
export const SET_CAT = 'SET_CAT'

// catActions.js

export const getCat = id => ({
  type: GET_CAT,
  id
})

export const setCat = (cat, id) => ({
  type: SET_CAT,
  id,
  cat
})

// catReducer.js
const initialState = {
  items: {}
}

const catReducer = (state = initialState, action) => {
  if (action.type === SET_CAT) {
    return {
      items: {
        ...state.items,
        [action.id]: action.cat
      }
    }
  }
}

// catMiddleware.js
const handleGetCat = (next, action) => {
  requestGetCat(action.id)
    .then(cat => next(setCat(cat, action.id)))
    // after retrieving the cat send an action to the reducers (or next middleware if it exist)
}

const actionHandlers = {
  [GET_CAT]: handleGetCat
}

// receive every actions passing by redux (if not blocked)
// store: { dispatch, getState }
// next: next middleware or reducers (that set redux state)
// action: a redux action (dispatched) with at least type property
const catMiddleware = store => next => action => {
  const handler = actionHandlers[action.type]
  if (handler) {
    handler(next, action)
  } else {
    // passing the action to the next middleware (or reducer - when there is no next middleware)
    next(action)
  }
}

// you have to apply your middleware
// and your reducer (see redux doc)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...