![Namecheap Takes Down Polyfill.io Service Following Supply Chain Attack](https://cdn.sanity.io/images/cgdhsj6q/production/6af25114feaaac7179b18127c83327568ff592d1-1024x1024.webp?w=800&fit=max&auto=format)
Security News
Namecheap Takes Down Polyfill.io Service Following Supply Chain Attack
Polyfill.io has been serving malware for months via its CDN, after the project's open source maintainer sold the service to a company based in China.
redux-thunk
Advanced tools
Package description
Redux Thunk is a middleware for Redux that allows you to write action creators that return a function instead of an action. This can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods `dispatch` and `getState` as parameters.
Asynchronous Actions
This feature allows for asynchronous actions within Redux. The code sample demonstrates how to create an action that fetches data asynchronously and dispatches different actions based on the result of the fetch.
function fetchData() {
return (dispatch) => {
dispatch({ type: 'FETCH_DATA_REQUEST' });
return fetch('https://api.example.com/data')
.then(response => response.json())
.then(json => dispatch({ type: 'FETCH_DATA_SUCCESS', payload: json }))
.catch(error => dispatch({ type: 'FETCH_DATA_FAILURE', error }));
};
}
Conditional Dispatching
Redux Thunk allows for conditional dispatching of actions based on the current state or any other condition. The code sample shows how to dispatch an action only if certain conditions are met, using the `getState` method to access the current state.
function updateDataIfNeeded(data) {
return (dispatch, getState) => {
if (shouldUpdateData(getState(), data)) {
dispatch({ type: 'UPDATE_DATA', payload: data });
}
};
}
Redux Saga is a library that aims to make application side effects (i.e., asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage, more efficient to execute, and better at handling failures. It uses generators to make those asynchronous flows easy to read, write, and test. Compared to Redux Thunk, Redux Saga provides a more powerful and complex solution for managing side effects, with more control over asynchronous actions.
Redux Observable is middleware for Redux that is used to handle asynchronous actions and side effects using RxJS observables. It allows for more complex asynchronous operations and provides a way to cancel them. Compared to Redux Thunk, Redux Observable offers a more declarative approach to handling side effects through observables, which can be more suitable for applications with complex asynchronous logic.
Readme
Thunk middleware for Redux.
npm install --save redux-thunk
A thunk is a function that wraps an expression to delay its evaluation.
// calculation of 1 + 2 is immediate
// x === 3
let x = 1 + 2;
// calculation of 1 + 2 is delayed
// foo can be called later to perform the calculation
// foo is a thunk!
let foo = () => 1 + 2;
Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch
and getState()
as parameters.
An action creator that returns a function to perform asynchronous dispatch:
const INCREMENT_COUNTER = 'INCREMENT_COUNTER';
function increment() {
return {
type: INCREMENT_COUNTER
};
}
function incrementAsync() {
return dispatch => {
setTimeout(() => {
// Yay! Can invoke sync or async actions with `dispatch`
dispatch(increment());
}, 1000);
};
}
An action creator that returns a function to perform conditional dispatch:
function incrementIfOdd() {
return (dispatch, getState) => {
const { counter } = getState();
if (counter % 2 === 0) {
return;
}
dispatch(increment());
};
}
npm install --save redux-thunk
Then, to enable Redux Thunk, use applyMiddleware()
:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';
// create a store that has redux-thunk middleware enabled
const createStoreWithMiddleware = applyMiddleware(
thunk
)(createStore);
const store = createStoreWithMiddleware(rootReducer);
Any return value from the inner function will be available as the return value of dispatch
itself. This is convenient for orchestrating an asynchronous control flow with thunk action creators dispatching each other and returning Promises to wait for each other’s completion:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
// applyMiddleware supercharges createStore with middleware:
let createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
// We can use it exactly like “vanilla” createStore.
let store = createStoreWithMiddleware(rootReducer);
function fetchSecretSauce() {
return fetch('https://www.google.com/search?q=secret+sauce');
}
// These are the normal action creators you have seen so far.
// The actions they return can be dispatched without any middleware.
// However, they only express “facts” and not the “async flow”.
function makeASandwich(forPerson, secretSauce) {
return {
type: 'MAKE_SANDWICH',
forPerson,
secretSauce
};
}
function apologize(fromPerson, toPerson, error) {
return {
type: 'APOLOGIZE',
fromPerson,
toPerson,
error
};
}
function withdrawMoney(amount) {
return {
type: 'WITHDRAW',
amount
};
}
// Even without middleware, you can dispatch an action:
store.dispatch(withdrawMoney(100));
// But what do you do when you need to start an asynchronous action,
// such as an API call, or a router transition?
// Meet thunks.
// A thunk is a function that returns a function.
// This is a thunk.
function makeASandwichWithSecretSauce(forPerson) {
// Invert control!
// Return a function that accepts `dispatch` so we can dispatch later.
// Thunk middleware knows how to turn thunk async actions into actions.
return function (dispatch) {
return fetchSecretSauce().then(
sauce => dispatch(makeASandwich(forPerson, sauce)),
error => dispatch(apologize('The Sandwich Shop', forPerson, error))
);
};
}
// Thunk middleware lets me dispatch thunk async actions
// as if they were actions!
store.dispatch(
makeASandwichWithSecretSauce('Me')
);
// It even takes care to return the thunk’s return value
// from the dispatch, so I can chain Promises as long as I return them.
store.dispatch(
makeASandwichWithSecretSauce('My wife')
).then(() => {
console.log('Done!');
});
// In fact I can write action creators that dispatch
// actions and async actions from other action creators,
// and I can build my control flow with Promises.
function makeSandwichesForEverybody() {
return function (dispatch, getState) {
if (!getState().sandwiches.isShopOpen) {
// You don’t have to return Promises, but it’s a handy convention
// so the caller can always call .then() on async dispatch result.
return Promise.resolve();
}
// We can dispatch both plain object actions and other thunks,
// which lets us compose the asynchronous actions in a single flow.
return dispatch(
makeASandwichWithSecretSauce('My Grandma')
).then(() =>
Promise.all([
dispatch(makeASandwichWithSecretSauce('Me')),
dispatch(makeASandwichWithSecretSauce('My wife'))
])
).then(() =>
dispatch(makeASandwichWithSecretSauce('Our kids'))
).then(() =>
dispatch(getState().myMoney > 42 ?
withdrawMoney(42) :
apologize('Me', 'The Sandwich Shop')
)
);
};
}
// This is very useful for server side rendering, because I can wait
// until data is available, then synchronously render the app.
store.dispatch(
makeSandwichesForEverybody()
).then(() =>
response.send(React.renderToString(<MyApp store={store} />))
);
// I can also dispatch a thunk async action from a component
// any time its props change to load the missing data.
import { connect } from 'react-redux';
import { Component } from 'react';
class SandwichShop extends Component {
componentDidMount() {
this.props.dispatch(
makeASandwichWithSecretSauce(this.props.forPerson)
);
}
componentWillReceiveProps(nextProps) {
if (nextProps.forPerson !== this.props.forPerson) {
this.props.dispatch(
makeASandwichWithSecretSauce(nextProps.forPerson)
);
}
}
render() {
return <p>{this.props.sandwiches.join('mustard')}</p>
}
}
export default connect(
SandwichShop,
state => ({
sandwiches: state.sandwiches
})
);
MIT
FAQs
Thunk middleware for Redux.
The npm package redux-thunk receives a total of 4,197,753 weekly downloads. As such, redux-thunk popularity was classified as popular.
We found that redux-thunk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Polyfill.io has been serving malware for months via its CDN, after the project's open source maintainer sold the service to a company based in China.
Security News
OpenSSF is warning open source maintainers to stay vigilant against reputation farming on GitHub, where users artificially inflate their status by manipulating interactions on closed issues and PRs.
Security News
A JavaScript library maintainer is under fire after merging a controversial PR to support legacy versions of Node.js.