compose-state
Compose multiple setState or getDerivedStateFromProps updaters in React.
compose-state
works with the standard setState
parameters – objects or functions – so you don’t have to learn any new syntax. It’s also compatible with React’s new getDerivedStateFromProps
lifecycle method.
Use
Install
yarn add compose-state
or npm install compose-state
Import
import composeState from 'compose-state';
// or
import {
composeState,
composeDerivedStateFromProps,
} from 'compose-state';
API
composeState([updaters])
Returns an updater that can be used with setState
. Calling this produces the same result as calling or accessing each given updater from right to left, merging each partial state. If a given updater is a function, its prevState
value is the previous state merged with the current partial state.
Arguments
Name | Type | Description |
---|---|---|
[updaters] |
(...Updater) |
Functions that can be used with setState , or partial state objects |
composeDerivedStateFromProps([updaters])
Returns an updater that can be set as a component's getDerivedStateFromProps
static value. Calling this produces the same result as calling or accessing each given updater from right to left, merging each partial state. If a given updater is a function, its prevState
value is the previous state merged with the current partial state.
Arguments
Name | Type | Description |
---|---|---|
[updaters] |
(...Updater) |
Functions that can be set as a component's getDerivedStateFromProps static value, or partial state objects |
Benefits
Simplify your updaters and React code
Let's say you want to call setState
and do two things
- Increment a score value by 1
- Log the current time to an array
Both of these updaters need to be functional, since they rely on the previous state for their return values.
const updateScore = s => ({ score: s.score + 1 });
const logTime = s => ({ log: [...s.log, Date.now()] });
Normally, we would need to call setState
for both of these functions
class Game extends Component {
onScore = () => {
this.setState(updateScore);
this.setState(logTime);
};
// ...
}
...or we rewrite the two updaters into one larger function.
const updateScoreLogTime = s => ({
score: s.score + 1,
log: [...s.log, Date.now()],
});
But with compose-state
, we can keep these two updaters independent, and we won't have to bulk up our component code with more setState
calls.
const updateScoreLogTime = composeState(updateScore, logTime);
class Game extends Component {
onScore = () => {
this.setState(updateScoreLogTime);
};
// ...
}
compose-state
isn't dependent on React at all, it's just a big reducer function. This allows you to build and compose as many updaters as you want while keeping your actual component code simple and maintainable.
Easily mix functional and object updaters
compose-state
accepts both objects and functions, just like setState
. This allows you to mix static and dynamic updaters without increasing the complexity of any individual parameter.
const defaultValue = { value: 0 };
const incrementOther = s => ({ other: s.other + 1 });
this.setState(
composeState(defaultValue, incrementOther)
);
Compatibility with getDerivedStateFromProps
compose-state
comes with a composeDerivedStateFromProps
function to use with React's new getDerivedStateFromProps
lifecycle method.
const updater1 = (nextProps, prevState) => {
// ...
}
const updater2 = (nextProps, prevState) => {
// ...
}
class App extends Component {
static getDerivedStateFromProps = composeDerivedStateFromProps(
updater1, updater2
)
// ...
}