Files
frontend-bootcamp/step2-07

Step 2.7

Lessons | Exercise | Demo

Redux Ecosystem

Redux is the most popular Flux implementation, and the ecosystem of related libraries has grown as a result. This is one of the reason why it is a very popular library in use by many products made by Microsoft as well.

There had been "awesome lists" that various github users have collected related to tech and articles about redux. Here's just one such list:

https://github.com/xgrommx/awesome-redux#react---a-javascript-library-for-building-user-interfaces

It is literally impossible to list out all the related tech. In this step, we introduce but one useful library that works with redux.

react-redux: the Official React Redux Binding

That's right, Redux doesn't only work with React. It can be used inside Vue.js, Angular, and React Native, to name a few.

Component

The store doesn't magically get passed to the views randomly. It has to be supplied by a react-redux component called <Provider>. It can be placed anywhere, but it's best to just make it available at the root the app:

const store = createStore(reducers);

const App = () => {
  return (
    <Provider store={store}>
      <div>Hello World!</div>
    </Provider>
  );
};

connect() higher order function

Connect store to view with react-redux. connect() is used to turn Redux store and dispatch functions into props inside React components. The state and action dispatchers are passed along with a <Provider> component.

const OldComponent = props => {
  return <div>{props.foo}</div>;
};

const NewComponent = connect(
  mapStateToProps,
  mapDispatchToProps,
  mergeProps,
  options
)(OldComponent);

The connect() function takes in a few functions that maps some portion of the state tree and dispatcher functions as props. It is a higher order function meaning that the return value of connect() is a function that decorates OldComponents into a NewComponent with all the mapped props.

This mapStateToProps function selects out portions of the state tree. This function informs the connected view when to re-render based on a shallow comparison from previous state.

function mapStateToProps(state) {
  return {
    foo: state.foo
  };
}

The mapDispatchToProps are functions that will trigger the action message dispatch mechanism of Redux. It looks like this:

function mapDispatchToProps(dispatch) {
  return {
    // the dispatched message COULD be generated by an
    // action creator instead
    addTodo: () => dispatch({ type: 'addTodo', ... })
  }
}

Exercise

  1. open up exercise/src/index.tsx and wrap <TodoApp> with <Provider> as instructed in the comment

  2. open up exercise/src/components/TodoFooter.tsx and erase the "nullable" type modifier (i.e. the ?) in the interface definition of TodoFooterProps

  3. Remove the export from export const TodoFooter = (props: TodoFooterProps) => {

  4. uncomment the bottom bits of code and fill in the implementation for mapStateToProps() and mapDispatchToProps() - feel free to use TodoListItem.tsx as a guide

  5. do steps 2, 3, and 4 for the TodoHeader.tsx file

Bonus Exercise

For further reading, go here to look up more information about the mergeProps and options parameters to connect():

https://react-redux.js.org/api/connect