This release introduces changes to error handling.
Previously, the parameter of the rejected promise callback was both the dispatched action and an error object. The middleware also always constructed a new error object, which caused unexpected mutation and circular references.
Now, the parameter of the rejected promise callback is the value of reject. The middleware does not construct a new error; it is your responsibility to make sure the promise is rejected with an Error object.
// beforeconstbar= () => ({ type:'FOO', payload:newPromise(() => {reject('foo'); })});.then(() =>null, ({ reason, action }) => {console.log(action.type):// => 'FOO'console.log(reason.message); // => 'foo'});// afterconstbar= () => ({ type:'FOO', payload:newPromise(() => {/** * Make sure the promise is rejected with an error. You * can also use `reject(new Error('foo'));`. It's a best * practice to reject a promise with an Error object. */thrownewError('foo'); })});.then(() =>null, error => {console.log(error instanceofError); // => trueconsole.log(error.message); // => 'foo'});
2.x to 3.0.0
This release introduces some major changes to the functionality of the middleware:
First, the middleware returns a promise instead of the action.
Third, promises can be explicitly or implicitly in the action object.
// beforeconstfoo= () => ({ type:'FOO', payload: { promise:Promise.resolve() }});// after, with implicit promise as the value of the 'payload' propertyconstbar= () => ({ type:'BAR', payload:Promise.resolve()});
Of course, if you prefer the explicit syntax, this still works. This syntax is also required for optimistic updates.
// after, but with explicit 'promise' property and 'data' propertyconstbar= () => ({ type:'BAZ', payload: { promise:Promise.resolve(), data:... }});
Fourth, thunks are no longer bound to the promise. If you are chaining actions with Redux Thunk, this is critical change.