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. |