Hacking Workbench2 » History » Version 2
Peter Amstutz, 02/13/2019 10:55 PM
| 1 | 1 | Peter Amstutz | h1. Hacking Workbench2 |
|---|---|---|---|
| 2 | |||
| 3 | The application logically begin in @workbench2/src/index.tsx@ with a call to fetchConfig() and then (when the promise is fulfilled) the constructs the major pieces of the application architecture: |
||
| 4 | |||
| 5 | 2 | Peter Amstutz | h2. Services |
| 6 | 1 | Peter Amstutz | |
| 7 | 2 | Peter Amstutz | "services" interact with external resources. These classes define methods for reading and writing to various types of backend (as far as I can tell, they don't hold any state themselves, but talk to external stateful services). Services defined include a service for each the API server endpoint that workbench uses, WebDAV server, workbench2 configuration like vocabulary and file viewers, and preferences kept in the browser local store. |
| 8 | |||
| 9 | h2. Store |
||
| 10 | |||
| 11 | 1 | Peter Amstutz | "store" is a "Redux":https://redux.js.org/ state container. State is divided into a groups. Each group defines a "reducer". A reducer is a function that takes (current state, action) and "reduces" it to a new state. At start, reducers are executed with an undefined state to get the initial starting state. After that, state is updated by "dispatching" an action to the state container. |
| 12 | |||
| 13 | 2 | Peter Amstutz | h2. App |
| 14 | |||
| 15 | The "App" is the root react component. It is invoked to regenerate the page, producing a "virtual DOM". ReactDOM merges the virtual DOM changes into the actual browser DOM. |
||
| 16 | |||
| 17 | h2. Interaction loop |
||
| 18 | |||
| 19 | # Render the DOM (based on state from redux store) |
||
| 20 | # User clicks on something |
||
| 21 | # onClick handler dispatches an action |
||
| 22 | # reducer produces a new state based on the action |
||
| 23 | # subscribers are notified that the state has changed |
||
| 24 | |||
| 25 | 'react-redux' links the data store to components use those state items. As part of defining a react component, call @connect@ with a function that extracts only the state required to render the component from the data store. This returns a function, call this with the actual react component definition. This optimizes re-rendering by only updating components that are potentially affected by a given state change. |
||
| 26 | |||
| 27 | h2. Defining new state items |
||
| 28 | |||
| 29 | @workbench2/src/store/store.ts@ |
||
| 30 | |||
| 31 | @createRootReducer@ defines the reducer groups. Pick one which is relevant, or define a new one. A reducer group "xyz" is defined in @workbench2/src/store/xyz/xyz-reducer.ts@ |
||
| 32 | |||
| 33 | Add the state item to @interface XyzState@ and @initialState: XyzState@ for the group. |
||
| 34 | |||
| 35 | h2. Defining new actions |
||
| 36 | |||
| 37 | Actions types are declared in @xyzActions@ in @workbench2/src/store/xyz/xyz-actions.ts@. |
||
| 38 | |||
| 39 | Actions are implemented in @xyzReducer@ in @workbench2/src/store/xyz/xyz-reducer.ts@ |
||
| 40 | |||
| 41 | The reducer for the action reduces (current state, action) to (new state). The new state must have all the state items. There is a shorthand syntax for this: @{ ...state, open: false }@ which means "construct a new object with all the items from 'state', except those declared explicitly" |
||
| 42 | |||
| 43 | A common pattern seems to be to define functions that can be called or used as event handlers that implement high level behaviors by calling services and dispatching actions. |