compose-state
is a library that composes multiple state 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.
yarn add compose-state
or npm install compose-state
import composeState from 'compose-state';
// or
import {
composeState,
composeDerivedStateFromProps,
} from 'compose-state';
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.
Name | Type | Description |
---|---|---|
[updaters] |
(...Updater) |
Functions that can be used with setState , or partial state objects |
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.
Name | Type | Description |
---|---|---|
[updaters] |
(...Updater) |
Functions that can be set as a component's getDerivedStateFromProps static value, or partial state objects |
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.
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)
);
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
)
// ...
}
It's just normal, boring React
While more formal state managers push developers away from controlling state in React, compose-state
simply enhances state control methods that are primitive to the platform.
compose-state
is a lot like Classnames. It's a helper function that makes setState
calls more declarative and easier to construct, just like how Classnames is a helper function that makes className
values more declarative and easier to construct.
Functional setState is the future of React by Justice Mba
Best kept React secret: you can declare state changes separately from the component classes. by Dan Abramov