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

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

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 on celsius. Then, fahrenheit is calculated based on kelvin.

  • When kelvin is updated, fahrenheit is calculated since it depends on kelvin. Then, celsius is calculated based on fahrenheit.

  • When fahrenheit is updated, celsius is calculated since it depends on fahrenheit. Then, kelvin is calculated based on celsius.

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

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: