Sallu
Sallu

Reputation: 489

React - I need advise how to design state data structure

I am working on cricket scoring Single page application in react.

It is using Redux to maintain its data and with every action i will be getting a new state.

My app has single rootReducer because everything is mingled. If a ball is thrown, batting and bowling both sides are updated.

The state is pretty complicated but I'm of opinion that it should be like this.

Please tell me if this state design is fine or I should somehow simplify it or change it?

var playerType = {
    id:             0,
    name:           '',

    // Batting stats
    runs:           0,
    four:           0,
    six:            0,
    ballsFaced:     0,
    battingNumber:  false,
    isBatting:      false,
    isOnStrike:     false,
    isOut:          false,
    outType:        '',

    // Batting Walkin stats
    walkInOver:     0,
    walkInBalls:    0,
    walkInTeamRuns: 0,

    // Batting Out stats
    walkoutWicket:  0,
    walkoutOver:    0,
    walkoutBalls:   0,
    walkoutTeamRuns:0,
    wicketBowler:   0,
    wicketFilder:   0,
    notOutPlayerId: 0,
    notOutPlayerRuns:0,

    // Bowling stats
    overs:          0,
    balls:          0,
    overRuns:       0,
    wickets:        0,
    isBowling:      false,

};

var teamType = {
    id:                 0,
    name:               "",
    runs:               0,
    overs:              0,
    balls:              0,  // This are only legal balls from 0 to 5
    isTossWon:          false,
    players:playerType  = []
};

// Initial State
var initialState = {
    matchId:        0,
    thisOver:       [],
    prevOver:       [],
    oversTotal:     0,
    teamBatting:    teamType,
    teamBowling:    teamType
}

Your thoughts?

Upvotes: 0

Views: 70

Answers (1)

David L. Walsh
David L. Walsh

Reputation: 24815

I would have a match reducer that models everything in the match, such as:

  • A collection of batsmen
  • A collection of bowlers
  • Fields for each extra type (byes, legbyes, noballs, wides)

To that I would add "live" information such as:

  • The current batsman on strike
  • The current batsman off strike
  • The current bowler bowling

Note that I would leave out data that can be "derived" from other pieces of state. For instance, the total score can be derived from the sum of the batsmen's scores plus the sum of the extras.

A possible instance of the match state might look like:

{
  batsmen: {
    48: {
      id: 48,
      name: 'David Warner'
      runs: 10,
      balls: 18,
    },
    64: {
      id: 64,
      name: 'Matthew Renshaw',
      runs: 2,
      balls: 20,
    },
  },
  byes: 2,
  legbyes: 0,
  noballs: 3,
  wides: 0,
  bowlers: {
    82: {
      name: 'Jimmy Anderson',
      balls: 18,
      runs: 6,
      wickets: 0,
    },
    93: {
      name: 'Stuart Broad',
      balls: 17,
      runs: 9,
      wickets: 0,
    },
  },
  batsmanOnStrike: 48,
  batsmanOffStrike: 64,
  currentBowler: 93,
}

You might want to dispatch an action for a discrete scoring event. e.g.

{
  type: 'RUNS_SCORED',
  runs: 3,
}

Your reducer might handle it in the following manner:

case 'RUNS_SCORED': {
  const batsman = state.batsmen[state.batsmanOnStrike];
  const bowler = state.batsmen[state.currentBowler];

  return {
    ...state,
    batsmen: {
      ...state.batsmen,
      [state.batsmanOnStrike]: {
        ...batsman,
        runs: batsman.runs + action.runs,
        balls: batsman.balls + 1,
      },
    },
    bowlers: {
      ...state.bowlers,
      [state.currentBowler]: {
        ...bowler,
        balls: bowler.balls + 1,
        runs: bowler.runs + action.runs,
      },
    },
    batsmanOnStrike: action.runs % 2 === 0 ? state.batsmanOnStrike : state.batsmanOffStrike,
    batsmanOffStrike: action.runs % 2 === 0 ? state.batsmanOffStrike : state.batsmanOnStrike,
  };
}

This example is imperfect and incomplete, but I hope it gives you the general idea.

Upvotes: 1

Related Questions