Rate this page:

Thanks for rating this page!

We are always striving to improve our documentation quality, and your feedback is valuable to us. How could this documentation serve you better?

Using Redux with Flex

In much of your development with the Flex UI, your component state can be informed by information that already lives in Flex - for example, you can get access to the current Task and render the Task data in your custom component.

There are some instances, however, in which adding information to a Task might compromise security, or even just add unnecessary data to the Task itself. In these cases, you can extend the Redux store of your Flex UI and pass the new subscription information to your custom components.

On this page, we’ll cover two strategies for modifying the Flex Redux reducer. The first relies on the Plugin Builder to extend your contact center that’s hosted on The second strategy involves directly modifying the way Flex builds Redux, and is ideal if you’re planning to host Flex on your own infrastructure.

Brief Intro to Redux

Redux is a software package that helps developers manage application state. Flex uses Redux to manage a bunch of application state - for example, a new Task appearing in the UI or an agent changing from Available to Busy are both examples of the application state changing. Redux offers you some nice features:

  • a single source of truth about the state of your application (called the store)
  • an interface for dispatching actions that will update the store
  • an architecture that makes it easy to test and debug state changes, and, perhaps most importantly,
  • an integration with React that allows your React components to subscribe to changes in the store.

Check out the Redux documentation to learn more about all of the great features it offers and become a Redux master. You can also get a useful overview of Redux in the Code Cartoon Intro to Redux.

Using Redux in Your Flex Plugin

When you use the Flex Plugin Builder, you’re already using Redux! The boilerplate plugin code includes all of the bits and pieces that you need to manage the Plugin UI state. You can learn all about building your first plugin here.

Once you have a plugin setup, you can find most of the boilerplate Redux code in src/states/CustomTaskListState.js. For the sake of easily reading this page, the content of the plugin builder files is located in the code samples on this page, so don't stress out if you can't set up your first plugin just yet.

        Redux Boilerplate


        Redux Boilerplate

        Defining an Action

        Let's start with the Action that will cause some change in the UI state. In the sample plugin, it’s called ACTION_DISMISS_BAR, and as you might imagine, it dismisses a bar at the top of the UI.

        You'll notice that there's a lot of places that say ACTION_DISMISS_BAR in the code.


        In the sample plugin code, we've created a variable called ACTION_DISMISS_BAR assigned it a string with the contents 'DISMISS_BAR'.

        Once the Flex UI is running, Actions will start flying all over the place. Redux needs a unique identifier to understand what all of these Actions are and what they should do to the application state. So, all dispatched actions need a name, and Redux will look up the set of instructions for how it should change state for actions with that particular name. In order to make sure that you don't confuse Redux, the best practice is to use variables, which ensure that the identifier stays consistent in all of the places you're using the action.

        You'll need the Action ID when you're writing your Reducer, Components, and tests. Using a variable for the name allows you to rename the Action REMOVE_BAR by changing it in a single place. You can feel confident that your code will run correctly across the entire code base (and look good in the Redux DevTools - but that's a story for another time!)

        Writing the Reducer

        The reducer is defined with the following function:

        export function reduce(state = initialState, action) {...}

        This function returns an updated version of the application based on the dispatched Action.

        So, what is the application state?

        const initialState = {
          isOpen: true,

        This Javascript object reflects a small slice of the application state. The Reducer's job is to apply the Action to the current state object to create an updated version of the state. It will then return the updated state to Redux. Redux will later combine this Reducer with a bunch of other reducers to create one big Store of your application state.

        Note that the Reducer returns a fresh copy of the state every time it processes an Action. If you just modify the state without returning it, your application state won't update properly. Learn more about these types of patterns in the Redux Style Guide.

        A Reducer is usually one long switch statement, with the various cases being your different Action names. In this case (ha! See what we did there?) the Reducer deals with two cases: if it sees an Action with the ACTION_DISMISS_BAR identifier, it changes the isOpen value to false. Otherwise, if it doesn't recognize the Action identifier (or there isn't one), it'll just maintain the current application state.

        Adding Plugin State to the Flex Store

        Now that you have this state object, you'll need to make it available to Flex. This happens in src/YourPluginName.js with the addReducer method. This is a method that Flex provides to include your reducer in the Flex store - so this is Flex code, not Redux. It makes your Reducer's state and associated logic available across the Flex UI.


              Accessing Redux from your Plugin Component

              Now that your Reducer logic is defined, you need to connect all of that logic to the UI. In the Plugin Builder sample app, this happens in src/components/CustomTaskList/CustomTaskList.Container.js.

                    Container Component Logic


                    Container Component Logic

                    In React, it's common to create a Container component that contains the logic for fetching data for the component and a Presentational component that handles the logic for rendering the component itself. Don't get too hung up on this pattern, but there are lots of resources out there if you're curious about learning more about why the Plugin Sample is structured this way!

                    The code here contains a couple of key pieces of logic:

                    // Import redux methods
                    import { connect } from 'react-redux';
                    import { bindActionCreators } from 'redux';
                    // Import the Redux Actions
                    import { Actions } from '../../states/CustomTaskListState';
                    import CustomTaskList from './CustomTaskList';

                    First, it imports everything that it needs from NodeJS packages and the Action/Component files in the React app

                    const mapStateToProps = (state) => ({
                        isOpen: state['sample'].customTaskList.isOpen,
                    const mapDispatchToProps = (dispatch) => ({
                      // Note: the plugin's sample code uses a function called bindActionCreators here
                      // For the sake of clarity, we're using the dispatch function directly here
                      dismissBar: dispatch(Actions.dismissBar),

                    Two functions, mapStateToProps and mapDispatchToProps, are defined. All React components have properties, or props, that you can use to change how the component is displayed. As the name implies, mapStateToProps describes what particular "chunks" of application state the component should know about. In this case, it's defining the value of isOpen.

                    mapDispatchToProps describes the Actions that the component can send to Redux. In this case, the component's dismissBar prop should have a function that can dispatch the DISMISS_BAR action.

                    export default connect(mapStateToProps, mapDispatchToProps)(CustomTaskList);

                    Finally, you'll see a fancy connect method. It associates those mapping functions with the presentational React component. Your presentational component's props will now have values defined by those functions.

                    You can see the magic at work in the Component code itself.


                          The component's isOpen prop also has a defined value, thanks to the mapStateToProps function.

                          const CustomTaskList = (props) => {
                            if (!props.isOpen) {
                              return null;

                          Here, it's being used to conditionally render the component HTML.

                          The component is invoking the dismissBar prop.

                          <i className="accented" onClick={props.dismissBar}>

                          This prop was defined with mapDispatchToProps, and allows the component to dispatch the DISMISS_BAR Action whenever a user clicks the close text.

                          Redux helps you create a flow of data through your whole plugin. The user interacts with the Component, which invokes the dispatch function. The dispatch function sends out the relevant Action to the Reducer. The Reducer takes whatever information is associated with that Action (in this case, toggling isOpen) and modifies the Redux Store to reflect what’s going on. At long last, the Component, which is subscribed to the Store, updates using the power of React, reflecting the new application state!

                          Redux has a complex data flow, but once you've mastered it, it makes reasoning about and testing complex apps - like the UI for an Omnichannel Contact Center - a lot easier.

                          Combine Your Application's Reducer and the Flex UI's Reducer

                          If you've built your own Redux application, you can extend your own UI to include all of the stateful goodness in Flex. This option is only recommended if you already have an existing React app - otherwise, Plugins are likely a better choice. The following sample code is a brief example of how you can integrate Flex into your own application.

                          import Flex from "@twilio/flex-ui"
                          import myReducer from './myReducerLocation'
                          // Use Redux's combineReducers method to add your reducer to the Flex reducer
                          const reducers = combineReducers({
                              flex: Flex.FlexReducer,
                              app: myReducer
                          const middleware = applyMiddleware();
                          // Redux builts a store using the reducers and applies Flex middleware
                          const store = createStore(
                          // Flex is instantiated with the new store, which includes your custom reducer
                              .Manager.create(configuration, store)
                              .then(manager => {     
                                      <Provider store={store}>
                                          <Flex.ContextProvider manager={manager}>
                                              <Flex.RootContainer />

                          What Next?

                          Rate this page:

                          Need some help?

                          We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.