# Ideas to improve mobile app developer experience ## Development, testing, and deployment ### Problems * Local development is a pain due to local build environment differences, long build times, native build errors, etc. * Testing proposed changes is a pain (many of the same reasons) * Deployment is a pain due to us having to do most of it manually, and having to manage 3 separate build processes: * Codepush * Xcode * Android studio ### Solutions * **Move to [Expo!](https://expo.dev/)** * Some challanges may need to be overcome, such as changing over our libraries to be compatible with the ones supported by Expo * Productivity payoff for this would be *huge!* * **Xcode and Android Studio not needed to do local development.** ## Data handling ### Problems * We are wrapping all the data we receive from APIs in model classes which * include a lot of boilerplate, * manually convert from `snake_case` to `camelCase` for every field, * modify some fields on a case-by-case basis, such as * replacing `null` or `undefined` with an empty list (`[]`), * replacing missing fields with `null`, * wrapping nested entities in class wrappers, * individually implement a `toJson()` method to manually convert all fields back from `camelCase` to `snake_case` again. * We are using an `objectCleanse` method all over the place on both incoming and outgoing data, which blurs the distinction between `null` and `undefined` properties, and has lead to some strange bugs. ### Solutions * Consider replacing model classes with [Runtypes](https://github.com/pelotom/runtypes) schemas. * Much lighter weight with no boilerplate! * Data would be kept in it's original form coming from the API, making things more consistent with dash-web. * You get data validation and TypeScript types for free. * Remove `objectCleanse` code * Any properties that are being handled incorrectly in the code should be dealt with individually. * Start using [TypeScript](https://reactnative.dev/docs/typescript) for new or updated code. * Would serve to document the expected shape of data, * Provide excellent IDE support during development, * Help make code refactoring much easier, * Safeguard against common bugs, such as NPEs, misspelled fields, etc. ## Global state ### Problems * Excessive boilerplate * Single concepts are split into multiple files, and hard to navigate. For example, to setup a single Redux action, and call it from a component, you must: * Create a constant storing a string uniqueless identifying the action, and store it in `reduxStore/actions`, * Create an action function returning an object containing the payload, and a `type` field set to the string above, * Create a reducer located in `reduxStore/reducers` which returns a copy of the redux store with the requested modification, * Map the action to the component using `mapDispatchToProps` * Declare the prop in `propTypes` * Call the action via `this.props.action(...)` * Redux does not support `async` actions, and requires an extra layer on top of the above to perform `async` operations -- called *"thunks"*. ### Solutions * Move from Redux to [Jotai](https://github.com/pmndrs/jotai) or [Recoil](https://recoiljs.org/). * Both cut way down on boilerplate, * Both have full support for `async`, * Both make it easier to group related state, actions, and selectors together. * Consider using [React Query](https://react-query.tanstack.com) to manage server data instead of global state.