Witamy na froncie

simple

React State Management workshop using Redux

Prepared by Bartosz LewiƄski (based on previous workshop by Grzegorz Rozdzialik)

Workshop repo: https://github.com/Blewin/react-redux-state-management-workshop

What will we learn today?

  • Solving problems from previous workshops - THE REDUX WAY
  • Redux basic elements (actions, reducers, selectors)
  • Redux & React debugging

Problem we are solving - state management

Prop drilling can get out of hand.

Prop drilling

Redux is an excellent solution for big projects*

What will we do today

We'll work on previous codebase - with Redux! We'll implement basic elements, and see how they interact. If time will allow - we'll go deeper!

Initial setup

  1. Pull the workshop repository: (ask for link in rocket chat)
git clone git@github.com:Blewin/react-redux-state-management-workshop.git
  1. npm install
  2. npm start
  3. Open http://localhost:3000/
  4. Explore the src directory

Unidirectional data flow

simple

Redux Model

advanced

State in Redux

{
  party: {
    isJumping: false,
  },
  accounts: {
    alice: 20,
    bob: -2,
    charlie: 13,
  }
}

Actions in Redux

dispatch({
    type: 'JUMP'
})
dispatch({
    type: 'JOIN PARTY',
    userId: 'alice'
    payload: {
        partyNr: 3,
    }
})

Reducer

function partyReducer(state = INITIAL_STATE, action) {
  switch (action.type) {
    case 'JUMP':
      return {
        ...state,
        isJumping: true,
      };

    default:
      return state;
    }
  }

Before action was reduced

dispatch({
    type: 'JUMP'
})
{
    isJumping: false,
    isWild: true,
}

After action was reduced

dispatch({
    type: 'JUMP'
})
{
    isJumping: true,
    isWild: true,
}

Connect

function mapStateToProps(state, props) {
  return {
    value: state.accounts[props.userId],
  }
}

function mapDispatchToProps(dispatch, props) {
  return {
    onIncrement: () => dispatch({type: 'INCREMENT', id: props.userId}),
    onDecrement: () => dispatch({type: 'DECREMENT', id: props.userId}),
  }
}

export const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);

Task 1 - what is happening here!?

Task 1: Figure out what was done to this app and have a feel how it works

First, let's find:

  • react views and where data is rendered from store
  • where actions are dispatched
  • reducers and where data is entered to store

Now let's look

at redux dev tools

Workshop guidelines

  • Branch task-X (e.g. task-1) - starting point for a step
  • Work on task-X branch. Use npm run test to verify your solution.
  • Clueless? Branch task-X-solution (e.g. task-1-solution) contains an example solution

Task 2 - Let's act on it.

Debugging is fun, but let's allow users to create users too.

Branch: task-2

Task: Modify BankStats to have a button that creates an account

Rules:

  • use classname new-account-button
  • connect action to a prop openNewAccount
  • export `mapDispatchToProps` (this is full unit test coverage task)

Let's look at my solution

Task 3 - Who wants to be selected?

Task: Display the number of accounts in Bank Stats - reintroducinng previous feature

Let's do it without tests!

Tools you'll learn to use: React update visualiser. https://chrome.google.com/webstore/detail/react-developer-tools

Let's look at my bad solution

and see why it's bad

If you want to, test in branch task-3-structured will guide you to a nicer solution

Let's look at proper solution

Task 4 - There are too many accounts! Let's reduce them.

Branch: task-4

Task: implement reducer to remove an account, and add button to do it

Rules:

  • use a button with text "DELETE" inside Counter
  • use action with type "DELETE" and attribute id

Advanced: add unit tests for reducer

Let's look at the solution

Stretch goal tasks!

  • Introduce action creators! (Important notion)
  • Display number of accounts with balance > 100 in Bank Stats
  • Click to select an account, then put the balance in Bank Stats
  • Watch for rerenders!

Homework & future work

  • where to put asynchronous operations ?
  • how to manage selectors ?

Questions

Thank you for your participation.