Подписка на действие redux в компоненте реакции

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

FETCH_REQUESTED
FETCH_SUCCEEDED
FETCH_FAILED

Наконец, если это удалось; он возвращает фактический ответ или объект ошибки.

У меня есть компонент, который должен определять, не удалось ли выполнить операцию, желательно подписавшись на действие FETCH_FAILED и отобразив сообщение об ошибке в зависимости от типа ошибки (404/401 и другие коды состояния)

export const fetchData = () => {
    return async (dispatch, getState) => {
        const appState = getState();

        const { uid } = appState.appReducer;

        await dispatch(fetchRequested());

        try {
            const response = await LookupApiFactory().fetch({ uid });

            dispatch(fetchSucceeded(response));

            return response;
        } catch (error) {
            dispatch(fetchFailed());

            return error;
        }
    }
}

Я новичок в redux и реагирую, поэтому я немного не уверен, что иду в правильном направлении, любая помощь будет оценена.

Вы не подписываетесь на акцию. Скорее вы сопоставляете свой компонент с магазином. когда магазин обновляется, ваш компонент будет соответствующим образом повторно отрисован. Вы можете сделать это с помощью mapStateToProps.

Sujit.Warrier 24.05.2018 11:11

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

animaonline 24.05.2018 11:34

этот код находится в обычном классе, а не в компоненте реакции?

Sujit.Warrier 24.05.2018 11:50

Да, это отдельный класс.

animaonline 24.05.2018 11:52

Я думаю, что у меня проблема, похожая на ту, что у вас есть - мне нужно вызвать функцию «успеха» при успешном вызове API. Однако мне нужно прислушиваться к этому отправленному действию, чтобы я мог внести значимые изменения пользовательского интерфейса (в моем случае закрыть модальное окно). Это не совсем то, что может принадлежать состоянию редукции. В библиотеке управления состоянием ngxs Angular вы можете подписаться на хранилище, когда было отправлено определенное действие. Мне в основном нужно сделать то же самое здесь, но с редукцией. Сейчас я использую обратные вызовы, но это грязно.

Tom 14.11.2018 12:11
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
4
5
9 726
3

Ответы 3

Чтобы реализовать правильный механизм обратного вызова и хранения redux, у вас должно быть хранилище для хранения всех ваших данных,

const store = createStore(todos, ['Use Redux'])

затем вы отправляете данные в хранилище,

store.dispatch({
  type: 'FETCH_FAILED',
  text: reposnse.status //Here you should give the failed response from api
});

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

store.subscribe(()=>{
  store.getState().some.deep.property
})

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

Предполагая редукторы,

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

const testReducers =(state,actione)=>{

    case 'FETCH_FAILED' : {

        return {
            ...state,{ error_in_response : true }
        }
    };

    default : return state;
}

В своем контейнере вы можете получить этот флаг и передать его своему компоненту.

Предполагая, что combineReducers используется для объединения редукторов;

const mapStateToProps=(state)=>{

    return {
        error_in_response : state.testReducers.error_in_response
    }
}
connect(mapStateToProps)(yourComponent)

В вашем компоненте это можно получить с помощью this.props.error_in_response

Да, но в каком месте можно обнаружить, что флаг установлен и, например, показать оповещение?

animaonline 24.05.2018 11:51

Это сопоставляет редуктор с реквизитом, но где мне отображать предупреждение на основе изменения?

animaonline 24.05.2018 11:55

в вашем компоненте, где вы передаете флаг, подключенный с помощью redux-connect

RIYAJ KHAN 24.05.2018 11:59

внутри метода рендеринга?

animaonline 24.05.2018 12:01

вы можете использовать внутри него или в другом жизненном цикле в зависимости от последовательности монтажа / демонтажа компонента

RIYAJ KHAN 24.05.2018 12:09

Наиболее распространенный подход - использовать функцию connect из библиотеки react-redux. Это HoC, который подписывается на изменения состояния. Взгляните на эту библиотеку, кроме того, она позволяет вам привязать создателей ваших действий к отправке, что дает вам возможность отправлять ваши действия из компонента.

Вы можете использовать это так:

import React from 'react';
import { connect } from 'react-redux';

const MyComponent = ({ data, error }) => (
  <div>
    {error && (
      <span>Error occured: {error}</span>
    )}

    {!error && (
      <pre>{JSON.stringify(data, null, 2)}</pre>
    )}
  </div>
);

const mapStateToProps = (state) => ({
  data: state.appReducer.data,
  error: state.appReducer.error
});

export default connect(mapStateToProps)(MyComponent);

Вы можете использовать условный рендеринг внутри вашего jsx, как я показал выше, или использовать условие защиты, например:

const MyComponent = ({ data, error }) => {
  if (error) {
    return (
      <span>Error occured: {error}</span>
    );
  }

  return (
    <pre>
      {JSON.stringify(data, null, 2)}
    </pre>
  );
}

Другие вопросы по теме