From 01ba1e3f46dff795f3a375fb95913db35b0c224b Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 1 Jan 2016 14:55:19 +0100 Subject: [PATCH] Make QA its own file As written in HowStuffWorks.md before this refactor, this section was to be factored out. (see https://github.com/webpack/react-starter/blob/99224e26972faf1c860cc5f39c1476de4cc1d263/NOTES/HowStuffWorks.md) --- NOTES/HowStuffWorks.md | 32 +------------------------------- NOTES/QA.md | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 31 deletions(-) create mode 100644 NOTES/QA.md diff --git a/NOTES/HowStuffWorks.md b/NOTES/HowStuffWorks.md index 290e3ff..7dc2ceb 100644 --- a/NOTES/HowStuffWorks.md +++ b/NOTES/HowStuffWorks.md @@ -26,7 +26,6 @@ Some (inconspicuously) used/relevant node modules are explicitly mentioned with * [How the server DB works.](#how-the-server-db-works) * [How the 'Random fail!' works.](#how-the-random-fail-works) * [How the build works.](#how-the-build-works) - * [Q&A Why](#qa-why) ***** @@ -139,33 +138,4 @@ Depending on what way you used to do this build, a different build configuration Most webpack configuration is in that shared config file, per entry. Only one main entry is defined. Pre-rendering happens depending on the custom config. This is where a lot of node modules (packages) come into play: loaders add JSX support, debug options are set, and the output is set to `build/` is set. -# Q&A Why -**Design choices explained.** -Ok, so now you know the how. But why do it that way? Questions about design choices, answered by the author(s). (Tobias Koppers) - -**(interim, this document should only concern the How question) :exclamation: TODO extract Q&A info and document it.** - -What is the argument for using items-store? (from https://github.com/webpack/react-starter/pull/49 ) -> Q: What was the argument for using items-store? -> A: -> -> I didn't want to write a new module. I actually tried using Reflux.js, but couldn't find a good workflow for pre-rendering, optimistic updates and merging of multiple writes. You could do it manually but that is something I would expect from a flux implementation. items-store is a very simple store base class that coordinate this behavior (the repo actually also contains a simple helper for actions and a react mixin, but these are theoretically independent and you don't have to use them with the store). -> -> items-store allows to serialize and deserialize the store data to inject the data after pre-rendering. It manages optimistic updates and merges multiple writes. But items-store only offers a simple key-value store API and forces you to map more complex operations (via store-helpers) to this model. It's just a caching layer with events to the remote API (which need to be provided in the constructor). -> -> items-store basically provides a "raw data" store, while other implementations give you the ability to write higher level stores. In items-store you need to put this higher-level behavior in store-helpers. The advantage is that this way basic functionality is already provided by items-store. -> -> Now there is an alternative to items-store, which could provide "pre-rendering" part too: http://fluxible.io/ they use dehydrate and rehydrate to (de)serialize to data from the stores and provide it to the client stores. - -Regarding the paths that store data travels (from https://github.com/webpack/react-starter/pull/51 ) -> Q: How is it triggered to refresh everything from the server, -> A: `config/mainApp.jsx` invalidates store data when you change the page. When the pages read the data again it is invalid and will be refetched. - -> Q: how does it propagate changes when the user edits items, and -> A: The component fires an action (from `app/actions.jsx`) on edit. The action is handled in `app/mainStores.jsx` and writes some items on stores. The stores update their internal cache (which is displayed on the page as optimistic update) and do server requests (through their registered handlers in `app/mainStores.jsx`. - -> Q: how do values travel before ending up in some components render() ? -> A: component requests values from store in getProps() -> `app/mainStores.jsx` read (unavailable or invalidated) data from server -> internal `items-store` cache for the store -> getProps() -> components this.props -> render() - -> Q: how does the queue combine multiple requests? I cant imagine subsequent add/remove/edits would result in just one rest call.. do they? -> A: items-store store a single update per entry. Any subsequent updateItem() call causes both updates to be merged (mergeUpdates from items-store). Requests from stores to the server are queued (queueRequest in app/mainStores.jsx). Here only a single ongoing request is allowed. All writes that happen in the meantime are merged into a single write. +For information about why some of these choices were made, check out [QA.md](QA.md)! diff --git a/NOTES/QA.md b/NOTES/QA.md new file mode 100644 index 0000000..c49c9be --- /dev/null +++ b/NOTES/QA.md @@ -0,0 +1,39 @@ +# Q&A Why + +Design choices explained + +## What was the argument for using items-store? + +> I didn't want to write a new module. I actually tried using Reflux.js, but couldn't find a good workflow for pre-rendering, optimistic updates and merging of multiple writes. You could do it manually but that is something I would expect from a flux implementation. items-store is a very simple store base class that coordinate this behavior (the repo actually also contains a simple helper for actions and a react mixin, but these are theoretically independent and you don't have to use them with the store). + +> items-store allows to serialize and deserialize the store data to inject the data after pre-rendering. It manages optimistic updates and merges multiple writes. But items-store only offers a simple key-value store API and forces you to map more complex operations (via store-helpers) to this model. It's just a caching layer with events to the remote API (which need to be provided in the constructor). + +> items-store basically provides a "raw data" store, while other implementations give you the ability to write higher level stores. In items-store you need to put this higher-level behavior in store-helpers. The advantage is that this way basic functionality is already provided by items-store. + +> Now there is an alternative to items-store, which could provide "pre-rendering" part too: http://fluxible.io/ they use dehydrate and rehydrate to (de)serialize to data from the stores and provide it to the client stores. + +([source](https://github.com/webpack/react-starter/pull/49)) + + +## How is the server refresh triggered? + +> `config/mainApp.jsx` invalidates store data when you change the page. When the pages read the data again it is invalid and will be refetched. + +([source](https://github.com/webpack/react-starter/pull/51)) + +## How does it propagate changes when the user edits items? + +> The component fires an action (from `app/actions.jsx`) on edit. The action is handled in `app/mainStores.jsx` and writes some items on stores. The stores update their internal cache (which is displayed on the page as optimistic update) and do server requests (through their registered handlers in `app/mainStores.jsx`. + +([source](https://github.com/webpack/react-starter/pull/51)) + +## How do values travel before ending up in some components render()? +> A: component requests values from store in getProps() -> `app/mainStores.jsx` read (unavailable or invalidated) data from server -> internal `items-store` cache for the store -> getProps() -> components this.props -> render() + +([source](https://github.com/webpack/react-starter/pull/51)) + +## How does the queue combine multiple requests? + +> A: items-store store a single update per entry. Any subsequent updateItem() call causes both updates to be merged (mergeUpdates from items-store). Requests from stores to the server are queued (queueRequest in app/mainStores.jsx). Here only a single ongoing request is allowed. All writes that happen in the meantime are merged into a single write. + +([source](https://github.com/webpack/react-starter/pull/51))