React Substate v3.6 - What's New?

Aug 22, 2020

In the latest version of React Substate, I made a few significant updates centered around performance and ease of use. My goal with this project has been simplicity of the API above all else, with performance as a very close second. I believe these changes will make the adoption of the module even easier with quicker time-to-value in both small and large projects. Anyway, here's the highlights:

"useDispatch"

You can now get a reference to the dispatch function without registering for state changes. This is super useful for components that want to fire changes while still being pure, or for components that useSubstate multiple times and only want to deal with one reference to dispatch. Here's a brief example:

Before

const MyComponent = () => {
    const [uiData, uiDispatch] = useSubstate(substates.uiData)
    const [serverData, dataDispatch] = useSubstate(substates.serverData)

    const handleClick = () => {
        uiDispatch(actions.uiData.showModal, {text: 'Hello, modal!'})
    }

    const handleModalClose = () => {
        dataDispatch(actions.serverData.update, {newData: 'abc123'})
    }
}

After

const MyComponent = () => {
    const dispatch = useDispatch()
    const [uiData] = useSubstate(substates.uiData)
    const [serverData] = useSubstate(substates.serverData)

    const handleClick = () => {
        dispatch(actions.uiData.showModal, {text: 'Hello, modal!'})
    }

    const handleModalClose = () => {
        dispatch(actions.serverData.update, {newData: 'abc123'})
    }
}

Pretty much anytime you need to use multiple substates, it'll be cleaner to also useDispatch if you need to modify state within the same component.

Passing multiple substates to "usePatchEffect"

Previously when using usePatchEffect you could either create a patch effect for all substate changes or changes to a single substate. Now, you can add a patch effect for changes to multiple substates without needing to call usePatchEffect multiple times. This brings the API in line with the useEffect hook and should help slim down the size of components using this functionality. Here's an example:

Before

const MyComponent = () => {
    const helperFunction = (patches) => {
        // Do something useful
    }

    usePatchEffect((patches) => {
        helperFunction(patches)
    }, substates.uiData)

    usePatchEffect((patches) => {
        helperFunction(patches)
    }, substates.serverData)
}

After

const MyComponent = () => {
    usePatchEffect((patches) => {
        // Do something useful here instead!
    }, [substates.uiData, substates.serverData])
}

Honorable Mention: Immer 7

The peer dependency on Immer has been moved from version 6 to version 7 to take advantage of all that Immer 7 has to offer. Version 6 will still work perfectly fine as far as React Substate is concerned, but users now have the option to move to version 7 without being hit with an npm peer dependency warning.

I sincerely hope that you find this library useful when you're using state management. If you have any questions or suggestions for how to improve it based on your workflows, definitely let me know!