Что касается Redux-thunk, если обработчик отправляет вызываемую функцию, почему бы не вызвать ее напрямую? - PullRequest
1 голос
/ 27 февраля 2020

Как я понимаю redux-thunk, это может быть

<button onClick={fn1}>Click Me</button>

, а в fn1 он отправляет не объект действия, но отправляет функцию fn2, поэтому что когда промежуточное ПО redux-thunk вызывает его (что означает fn2), вызовите вызов fetch или Ajax и разрешите обработчику выполнения then или обратному вызову Ajax отправить объект действия, например

{ type: "DATA_RECEIVED", data: data }

но почему бы fn1 напрямую не позвонить fn2 для выполнения задачи, а позволить промежуточному программному обеспечению вызвать ее вместо этого?

Ответы [ 2 ]

1 голос
/ 27 февраля 2020

Redux Thunk - это тонкое промежуточное ПО очень (например, толщиной 14 строк), которое вводит соглашение, согласно которому Redux должен знать, как обращаться с асинхронными процессами для вас.

Вы сказали

дело в том, что вы хотите, чтобы fn2 немедленно сработал. Например: пользователь нажимает кнопку, чтобы получить что-то, вы хотите, чтобы функция, выполняющая выборку, или Ajax запускалась немедленно. Я думаю, что с redux-thunk, если вы отправляете функцию, она запускается немедленно

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

Независимо от того, что Redux понадобится отправить действие в более позднее время. Redux Thunk делает «позже» за вас.

Примите во внимание следующие различия:

const store = {
  dispatch() {
    console.log("Dispatch");
  }
};

// Action creator that retuns an action
const inc = () => ({
  type: "INCREMENT"
});

// Impure action creator that you shouldn't use
const badAsyncInc = () => {
  setTimeout(() => {
    store.dispatch({
      type: "INCREMENT"
    });
  }, 1000);
};

// Action creator that returns a function that takes dispatch as arg
const aInc = () => dis => setTimeout(() => dis({
  type: "INCREMENT"
}), 1000);

/*
 * The following will do everything including waiting to dispatch
 * and dispatching to the store.  That's good, but not good for
 * when we want to use a different store.
 */
badAsyncInc()();

/*
 * The following is the "manual" way of wiring up the delayed
 * dispatch that you have to do without Redux Thunk.
 */
aInc()(store.dispatch);

/*
 * With Redux Thunk, this will call the "fn2" immediately but also
 * pass the dispatch function to "fn2" for you so that you don't 
 * have to wire that up yourself.
 */
store.dispatch(aInc);

В этом случае вы можете просто позвонить badAsyncInc и все будет сделано, так как он вызовет store.dispatch для вас. Но что, если у вас есть несколько магазинов? Что делать, если вы хотите использовать магазин для тестирования? Что если вы хотите полностью издеваться над магазином? Ваш badAsyncInc теперь связан с магазином, что плохо для создателей действий.

В качестве альтернативы, вы можете просто вызвать aInc самостоятельно и передать ему функцию отправки. Однако зачем это делать, если все ваши другие создатели действий пишутся как store.dispatch(actionCreator()). Redux Thunk помогает вам сохранить этот шаблон даже с асинхронными c действиями.

Redux Thunk пытается помочь вам написать создателей действий, которые слабо связаны и тестируемы.

0 голосов
/ 27 февраля 2020

в fn1, он не отправляет объект действия, но отправляет функцию fn2

Мотивация отправки функции заключается в том, что функция включает в себя аргумент отправки (который предоставляет Redux Thunk) для вас, чтобы использовать.

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

const action = (url) => async (dispatch) => {
    try {
        const response = await fetch(url);
        dispatch(success(response));
    } catch (error) {
        dispatch(failure(error));
    }
}

Диспетчеризация позволяет вам отправлять успешное или неудачное действие для ваших редукторов.

Подробнее: https://redux.js.org/advanced/async-actions/#async -action-creators

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

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

...