Создать слушателя Redux-саги - PullRequest
       13

Создать слушателя Redux-саги

0 голосов
/ 28 декабря 2018

У меня есть действие UPDATE_DATE в саге о редуксе.Я хочу обновлять несколько ресурсов каждый раз, когда изменяется Дата.Я хотел бы реализовать слушателя к действию UPDATE_DATE_SUCCESS, которое запускает обратный вызов.Любая идея?Было бы здорово, если бы я мог вызвать его из компонента React.

Действие: UPDATE_DATE UPDATE_DATE_SUCCESS UPDATE_DATE_FAILURE

export const {
  updateDate,
  OnDateChange,
} = createActions({
  [ActionTypes.UPDATE_DATE]: (date) => date,
});

Saga

export function* updateDate(newDate) {
  console.log('from sagas to reducer', newDate); // eslint-disable-line no-console
  try {
    yield put({
      type: ActionTypes.UPDATE_DATE_SUCCESS,
      payload: newDate,
    });
  } catch (err) {
    /* istanbul ignore next */
    yield put({
      type: ActionTypes.UPDATE_DATE_FAILURE,
      payload: err,
    });
  }
}

export default function* root() {
  yield all([
    takeLatest(ActionTypes.UPDATE_DATE, updateDate),
    takeEvery(ActionTypes.UPDATE_DATE_SUCCESS, test),
  ]);
}

Желательная реализация в компоненте React

  componentDidMount() {
    const { dispatch } = this.props;

    dispatch(onDateChange((newDate) => {
        dispatch(getApps(newDate));
        dispatch(getPlatforms(newDate));
        dispatch(getNetworks(newDate));
        dispatch(getCountries(newDate));
        dispatch(getFormats(newDate));
        dispatch(getDevices(newDate));
        dispatch(getNetworkKeys(newDate));
    }));
  }

Любая помощь?спасибо!

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Идея Redux Sagas заключается в том, чтобы обрабатывать side-effects действия / события в Saga, а не в компонентах.Я думаю, что способ сделать это будет что-то вроде этого (обратите внимание, что фрагмент кода не проверен, используйте его только в качестве ссылки / примера):

// --> Saga <-- //
import { getApps, getPlatforms, getNetworks, getCountries, getFormats, getDevices, getNetworkKeys } from './actions.js';

export function* updateDateWatcher(action) {
  const { payload: newDate } = action;
  if (!newDate) return;

  try {
    // dispatch all required actions
    yield all([
      put(getApps(newDate),
      put(getPlatforms(newDate),
      put(getNetworks(newDate)),
      put(getCountries(newDate)),
      put(getFormats(newDate)),
      put(getDevices(newDate)),
      put(getNetworkKeys(newDate)),
    ]);
    // then trigger a success action if you want to
    yield put(updateDataSuccess());
  } catch (err) {
    // if something wrong happens in the try this will trigger 
    yield put(updateDateFailure(err));
  }
}

export default function* root() {
  yield all([
    takeLatest(ActionTypes.UPDATE_DATE, updateDateWatcher),
  ]);
}


// --> Component <-- //
import { updateDate } from './actions.js';

class MyComponent extends Component {
  componentDidMount() {
    const { onDateChange } = this.props;
    const date = new Date();
    onDateChange(date); // -> triggers ActionTypes.UPDATE_DATE
  }
}

const mapDispatchToProps = dispatch => ({
  onDateChange: (newDate) => dispatch(updateDate(newDate)),
});

export default connect(null, mapDispatchToProps)(MyComponent);
0 голосов
/ 28 декабря 2018

Я не совсем понимаю, что вы пытаетесь сделать, но ... если вам просто нужен слушатель, почему бы просто не подписать действие, которое прослушивает определенное действие?

 function * mySuperSagaListener() {
    const listener = yield take('some_action_name')
    // calculate the new state here
    // here
    // here
    // when you are done... update the state
    const updateState = yield put({type: 'some_action_name_update', payload: newState})
 }

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

 dispatch({type: 'some_action_name'})

Best!

...