it-roy-ru.com

React Redux диспетчерское действие после другого действия

У меня есть действие async, которое извлекает данные из API REST:

export const list = (top, skip) => dispatch => {
    dispatch({ type: 'LIST.REQUEST' });

    $.get(API_URL, { top: top, skip: skip })
        .done((data, testStatus, jqXHR) => {
            dispatch({ type: 'LIST.SUCCESS', data: data });
        });
};

A sync действие, которое меняет состояние skip:

export const setSkip = (skip) => {
    return {
        type: 'LIST.SET_SKIP',
        skip: skip
    };
};

Начальное состояние для top = 10, skip = 0. В компоненте:

class List extends Component {
    componentDidMount() {        
        this.list();
    }

    nextPage() {
        let top = this.props.list.top;
        let skip = this.props.list.skip;

        // After this 
        this.props.onSetSkip(skip + top);

        // Here skip has previous value of 0.
        this.list();
        // Here skip has new value of 10.
    }

    list() {
        this.props.List(this.props.list.top, this.props.list.skip);
    }

    render () {
        return (
            <div>
                <table> ... </table>
                <button onClick={this.nextPage.bind(this)}>Next</button>
            </div>
        );
    }
}

Когда кнопка Далее при первом нажатии, значение skip, которое использует асинхронное действие, не изменилось. Как я могу отправить действие после синхронизация действия?

10
Denis Bednov

Спасибо за ответы, но я сделал это так:

let top = this.props.list.top;
let skip = this.props.list.skip;
let newSkip = skip + top;

this.props.onList(top, newSkip);
this.props.onSetSkip(newSkip);

Сначала я вычисляю новое skip и отправляю асинхронное действие с этим новым значением. Затем я отправляю действие syns, которое обновляет skip в состоянии.

0
Denis Bednov

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

Итак, следует этот поток:

Синхронизация действий вызова -> вызов редуктора ---> кейс-функция (редуктор) ---> кейс-функция (редуктор)

Вместо обычного потока, который, вероятно, это для вас:

Синхронизация действий вызова -> вызов редуктора

Следуйте этому руководству, чтобы разделить редукторы вверх , чтобы увидеть, что такое редукторы.

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

Пример для Thunks :

export const setSkip = (skip) => {
    return (dispatch, getState) => {

        dispatch(someFunc());
        //Do someFunc first then this action, use getState() for currentState if you want
        return {
            type: 'LIST.SET_SKIP',
            skip: skip
        };
    }
};
4
Martin Dawson

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

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

this.props.onList(top, newSkip);
this.props.onSetSkip(newSkip);

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

export function onList(data) {
  return (dispatch) => {
          dispatch(ONLIST_REQUEST());
    return (AsyncAPICall)
    .then((response) => {
      dispatch(ONLIST_SUCCESS(response.data));
    })
    .catch((err) => {
      console.log(err);
    });
  };
}

export function setSkip(data) {
      return (dispatch) => {
              dispatch(SETSKIP_REQUEST());
        return (AsyncAPICall(data))
        .then((response) => {
          dispatch(SETSKIP_SUCCESS(response.data));
        })
        .catch((err) => {
          console.log(err);
        });
      };
    }

export function onListAndSetSkip(dataForOnList) {
  return (dispatch) => {
     dispatch(onList(dataForOnList)).then((dataAfterOnList) => {
       dispatch(setSkip(dataAfterOnList));
     });
  };
}
4
pierreg

также проверьте это redux-sequence-action

0
zarehb