redux-autosetters
redux-autosetters provides automatic setters and getters for all properties in the Redux store.
How to use:
This is a “Github” component. To use it, add the following in package.json under dependencies:"redux-autosetters": "https://github.com/precision-sustainable-ag/redux-autosetters#v1.0.0"
Then run:npm i
Example:
Without redux-autosetters | With redux-autosetters |
---|---|
store.jsx import { configureStore, createSlice } from '@reduxjs/toolkit';
const temperatureSlice = createSlice({
name: 'temperature',
initialState: { temperature: 0 },
reducers: {
setTemperature: (state, action) => {
state.temperature = +action.payload;
}
}
});
export const { setTemperature } = temperatureSlice.actions;
export const store = configureStore({
reducer: temperatureSlice.reducer,
}); | store.jsx import { createStore } from 'redux-autosetters';
const initialState = { temperature: 0 };
export const store = createStore(initialState, {});
export { set, get } from './redux-autosetters'; |
app.jsx import {
Provider, useDispatch, useSelector,
} from 'react-redux';
import { store, setTemperature } from './store';
const Temperature = () => {
const { temperature } = useSelector((state) => state);
const dispatch = useDispatch();
return (
<div>
Temperature:
<input
type="number"
value={temperature}
onChange={(e) => {
dispatch(setTemperature(e.target.value))
}}
/>
</div>
);
};
const App = () => (
<Provider store={store}>
<Temperature />
</Provider>
);
export default App; | app.jsx |
Here's an example temperature converter:
Without redux-autosetters | With redux-autosetters |
---|---|
store.jsx | store.jsx |
app.jsx | app.jsx |
Notice how the calculations have shifted from the store to the component.
However, this isn't strictly necessary. With redux-autosetters, you can keep these calculations in the store by using functional properties — something typically not allowed in standard Redux:
Notice the use of ||
to set the default value for celsius
. Defaults weren't provided for kelvin
or fahrenheit
, because redux-autosetters will automatically initialize them based on the celsius
value.
When
celsius
is updated,kelvin
is calculated since it depends oncelsius
. Then,fahrenheit
is calculated based onkelvin
.When
kelvin
is updated,fahrenheit
is calculated since it depends onkelvin
. Then,celsius
is calculated based onfahrenheit
.When
fahrenheit
is updated,celsius
is calculated since it depends onfahrenheit
. Then,kelvin
is calculated based oncelsius
.
To avoid infinite loops, redux-autosetters ensures that a property won't be recalculated if it’s already being used in the current calculation.
For example, when celsius
is changed, it calculates kelvin
, which calculates fahrenheit
. However, this change to fahrenheit
will not cause another recalculation of celsius
.
Here’s the comparison, now using functional properties:
Without redux-autosetters | With redux-autosetters |
---|---|
store.jsx | store.jsx |
app.jsx | app.jsx |
redux-autosetters works at any depth within the initialState
.
For example, given the following state:
You can update city
like this:
You can pass a callback to update the current value of a property as well:
When using functional properties with nested values, be sure to include the complete path in the calculations: