vendredi 30 juin 2017

Flux design pattern and good practices

This is going to be lengthy post, containing my questions, backed with examples from the first Flux project, I recently created. I will split it into two sections and try to numerate my questions, for easier responses. If you know a good place where I can read about the topic - please share. I've done my reading, but I find it a bit hard to locate information regarding to general best practices. Here we go.

Section 1: General questions

1) Multiple stores per view component

Is it a good practice for a single container (or higher order component) to depend on multiple stores. That may cause a lot of unused properties in the component's state. Is that a problem? If it is I could get state like this:

//constructor
this.state = { 
    field1: // from Store1
    field2: // from Store2
}

//componentDidMount
Store1.listen(this.updateFromStore1)
Store2.listen(this.updateFromStore2)

//updateFromStore1
this.setState({
    field1: state.field1
});

I think such an approach would separate the data across stores very well - UserStore will only hold info about the user, {data}Store will only hold information about it's type of data. And every component can take whatever it needs from all the stores. Or should it be more like - every container has its own store, which would lead to data-repetition, but cleaner project.

2) Use single store for multiple components

For example - a FormStore, which is responsible for holding information about every form in our application. all fields of our forms are held there, and only those of the currently mounted component(for example UserRegister) are initialized and used. This may result in a lot of unused fields, with null value in the state, but again we could prevent that, if we select only the fields we are using, as I described above.

3) What should be responsible for loading the initial data?

I designed my app in a way that when a component mounts, it fires action method, which calls server for data, and then fires a Success of Fail action, which updates the store. But i read somewhere that stores can get the initial data internally, and then actions will be used only to change that data. If stores are to be responsible for this, when and how should that work?

4) The concept for actions:

Are actions supposed to drive everything, or are they only necessary when we update data. For example I have tried redirecting within actions and I get simultaneous actions error, because the component I redirected to, fires action inside componentDidMount to get more data. Maybe this would not be a problem if a store handles initial data internally.

Section 2: Specific questions

1) User authorization

URL based restriction is easy. I used another HOC on top of my container, which listened to UserStore and redirected to Login page, if there is no logged in user. But how would I hide a button, down in my component chain? I used the same approach (but instead of redirecting, I just didn't render the button). But that's sort of violation of Flux's rule, that all actions and stores should be operated by the container components only. Is there a better approach.

2) Self-contained statefull components

Flux docs say that best case would be if all view components are stateless. But what If I have an expandable view component? For example I have a box, with Book summary and a Read more button. When the button is pressed the box expands and additional information is shown. My solution would be to keep a state self-contained inside the component, which holds component-specific information. Logically I don't think there is any point for stores, which don't hold actual data. Any thoughts?

3) Forms located lower in the component chain

This may be similar to 2), but I think forms are a bit different. For Example, I have list of movies, on every movie you can click the "Comments" button, which will show the comments and also a form, to add new comment. How to handle that form? Self-contained logic and state? What I did was to add comment field to my FormStore, and reuse it and FormActions (The same actions and stores I use for every from there is in my app).

Aucun commentaire:

Enregistrer un commentaire