Package: dash-redux
dash-reduxProvides Plotly/Dashwith support for a Redux stylestore of truth.pip install dash-reduxIn theReduxStorecomponent,stateis derived from any number automatically generated
surrogate stores. The surrogate stores are presented to the application for update via callbacks.
When a callback completes, the updated surrogate is copied to a master
store. This mechanism acts as a data multiplexor feeding application state changes from Dash UI events
into an immutablesingle source of truththat can then be used to trigger
additional activity in the UI.The application interfaces with the store using the callbacks@Redux.update(...). This
callback defines Dash IO to be used by the callback handler in the normal way. When
triggered by a Dash event the associated function is called with the IO statetogether with a reference to a surrogate storethat contains a copy of the master store. The callback
modifies the state as required and returns the store state.ReduxStorethen copies the
new state into the master store. This, in turn, triggers an event on the master store
that can be used by the application in standard Dash callbacks.ReduxStorealso supports anaction_functionexecution model that enforces a formal
separation of the Dash/UI from the model.Update function:Redux = ReduxStore(id='store', data = { "todo": []})

@Redux.update(button.input.n_clicks, input.state.value)
def new_activity(button_clicks, input, state):
    if button_clicks and input:
          state['todo'].append(input)
    return stateAction function:from .todo_model import TODO_MODEL, ModelActions as action

Redux = ReduxStore(id='store', data=TODO_MODEL)

@Redux.action(button.input.n_clicks, input.state.value)
def _add(button_clicks, input):
    if button_clicks and input:
        return action.add, input
    else:
        NOUPDATE

...todo_model.py:class ModelActions:

    def add(state, input):
        current = state.todo.copy()
        state.past.append(current)
        state.todo.append(input)
        state.future = []
        return state

    def delete(state, index):
        state.past.append(state.todo.copy())
        state.todo.pop(index)
        return state

    def undo(state):
        if len(state.past) > 0:
            state.future.append(state.todo)
            state.todo = state.past.pop()
        return state

    def redo(state):
        if len(state.future) > 0:
            state.past.append(state.todo)
            state.todo = state.future.pop()
        return stateThe snippets are taken from the todo example. Seetodo/todo.py.TODO ExampleAn eighty line todo application demonstrates theReduxStore. User input
is added to the todo list. Elements from the list can be deleted. The
example also provides UNDO and REDO buttons that demonstrate how to
easily manage an applications state history.To run the application clone this repository, then:pip install -r requirements.txt

python app.pyBuild the projectThe dash-redux package is available onpypi. If needed, to create a local
tarball, first change the release version indash_spa/_version.py, then:rm -rf dist dash_spa.egg-info build

python setup.py sdist bdist_wheelThe tarball is indist/dash_spa-.tar.gzTo install the tarball in a dash project:pip install dash_spa-<version>.tar.gzTestingPytest andDash Duoare used for testing. To run
these tests both the Chrome browser and Chrome driver must be installed.To run the tests:pytestPublishtwine upload dist/*