-
Notifications
You must be signed in to change notification settings - Fork 16
Store only active page state in the model #2
Comments
That is what I thought at first too but storing the sub states is necessary: the top-level components sometimes need to "peek" into the data of other components in the UI tree to decide whether or not to add or remove functionality. For example, the UI of Having a DU makes sense if the components are not related to each other, but this is not the case here. Also, I am seperating information on current page from the state of the page: I don't want it to be possible to change the current page of the next state in my
Components don't maintain their "current active page", that is decided from url and is propagated directly to the // App/Admin/Backoffice -> View.fs
// currentPage comes from "outside"
let render currentPage (state: State) dispatch =
match currentPage with
| Home ->
homePage dispatch
| NewPost ->
NewArticle.View.render state.NewArticleState (NewArticleMsg >> dispatch)
| Drafts ->
Drafts.View.render state.DraftsState (DraftsMsg >> dispatch)
| PublishedPosts ->
PublishedPosts.View.render state.PublishedPostsState (PublishedPostsMsg >> dispatch)
| EditArticle articleId ->
EditArticle.View.render state.EditArticleState (EditArticleMsg >> dispatch)
| Settings ->
Settings.View.render state.SettingsState (SettingsMsg >> dispatch)
Performance of modifying the state record is negligible: it is a simple operation that doesn't occur many times, unless I am running it 1000s of times, it not is important |
Components should avoid at most being related to each other. In fact, if they need to interact with each others, it should be throught /// Child update
let update model msg : Model * Cmd<Msg> * ExternalMsg =
// do something
/// Parent point of view
let update model msg =
match msg with
| Loaded (TabGeneral generalModel), GeneralInfoMsg subMsg ->
let (generalInfoModel, generalInfoCmd, externalMsg) = GeneralInfo.update generalModel subMsg
let newModel =
match externalMsg with
| GeneralInfo.ExternalMsg.NoOp ->
Loaded(originalData, TabGeneral generalInfoModel, toggleStateModel)
| GeneralInfo.ExternalMsg.DomainUpdated domainInfos ->
Loaded(domainInfos, TabGeneral (GeneralInfo.init domainInfos), toggleStateModel)
newModel, Cmd.map GeneralInfoMsg generalInfoCmd
Store the This point isn't clear for me.
I think I understand what you mean, but my application is changing is Page state or current page only by changing the url either manually or using some helpers like
Depending on what you store in your model the performance are impacted. We saw it at work Also, by storing each components state all the time you can easily show the previous state if you are not careful. Nothing force you to reset their state when the url changes. |
They are not related by the code and they don't know each other even exist, they are conceptually related
That is exactly what I am doing, see the "Message Inteception by example" in README, although I don't use external msg, I use just // Child -> Dispatches message "Logout"
| Logout -> state, Cmd.none
// Parent -> Intercept child message "Logout" and update state without passing it down to child (only if needed)
| BackofficeMsg childMsg->
match childMsg with
| Backoffice.Types.Msg.Logout ->
// intercept logout message of the backoffice child
let nextState, _ = init()
nextState, Urls.navigate [ Urls.posts ]
| _ ->
match state.SecurityToken with
| Some token ->
let prevBackofficeState = state.Backoffice
let nextBackofficeState, nextBackofficeCmd =
// pass auth token down to backoffice
Backoffice.State.update token msg prevBackofficeState
let nextAdminState = { state with Backoffice = nextBackofficeState }
nextAdminState, Cmd.map BackofficeMsg nextBackofficeCmd
| None ->
state, Cmd.none
That is exactly what I am doing, I am storing I think we are actually doing the same things, I am just calling it different names, I need to see more large examples and compare. I learned these concepts by exploring different idea's and seeing how it works out, so I am curious how others are doing it as well 😄 |
Indeed it's similar, for the access to the token. You still "break" the components independency because even if the From my point of view, this is the role of the parent to store the In theory, by doing that your components are more reusable (not much I do agree :) ) Sorry, I didn't read the whole code and only looked at the Indeed you are using a By having: type ExternalMsg =
| NoOp
| SetUser of User If I add a new case to Yes, we are indeed having the same idea just didn't implement the exact same structure :). This is a good news, as for me this ideas is one fo the missing pieces from the actual tutorials.
This is planned since a long time for me to write a complexe application and open source the code to make a tutorial of it. I still need to create/update one or two libraries before being ready for it... |
Thanks for the clarification, I think I will adopt the
I know I could remove |
With the current AppState, you are storing a lot of information.
In general, when you are on the
admin
section , you don't need thePosts
section state. For this reason, instead of creating oneproperty
in a record per children I prefer to use a DU.Another reason in favor of this, is it's make the update function quicker. Because you can reduce the number of nested record and also need to copy less data.
The text was updated successfully, but these errors were encountered: