Given I have an AJAX based search field that reacts on user input, requests search results from a backend via AJAX, shows the results in a dropdown below the search field, allows navigation through the search results via cursor keys and reacts on esc
key presses in an intelligent way.
Since the current Backbone based component is broken in many ways, I'd like to reimplement that search component using React
and maybe Flux
architecture.
During planning it turned out, that my component has at least a number of 10 different states (maybe even more), it has to react to actions
triggered by user inputs, and as well to actions
triggered by asynchronous server responses.
Question1: Should I model all state in a store
instead of a the parent component? That meant, that every user input changes the stores state, for example the :searchQuery
, :searchResults
and my parent view component reacts to that state changes?
Question2: Or should I model all state in the parent component itself and omit a store
, dispatcher
and actions
completely?
Question3: Independently from handling state in a store
or in the parent component itself, it turned out, that the component itself can have at least 10 different states, and there should only be a certain number of transitions allowed. Usually, I'd pull in a statemachine implementation here, model all :states
and allowed :transitions
and execute transitions everytime an action is received by the store
or a callback method is called in the parent component. What is the correct React way
to handle states
and transitions
between these states
in a component?
Question4: Which is the to-go-state-of-the-art Flux
implementation for Javascript? I have seen reflux so far, but I'm not sure, that's my poison.
I am open to all kind of suggestions here.
I am building a similar component in React
with flux
right now and I have worked with Backbone
extensively in the past so hopefully I give you some insight.
My guess is that your Backbone
solution had a model local to your search view that built :searchQuery
when the field(s) were updated. On the ajax callback you most likely just directly updated the :searchResults
.
1-2:
With flux
there ends up being a bit more boilerplate code, but in my experience if I don't build a store to start with I always regret it. That being said I would make a SearchStore
for the :searchResults
and keep the :searchQuery
in the state of the parent component.
This way when you are ready to call your search you use a view action SearchViewActions.getSearchResults(:searchQuery)
which makes the ajax call and in the callback calls SearchServerActions.receiveSearchResults(:searchQuery, :searchResults)
and updates the store. Then your results component can listen for Store
changes and call SearchStore.getResults()
when it sees the change. This helps modularize the two sub-components, where as option 2 would tightly couple the two components and make it harder for outside component reuse.
3:
I like your solution of the state-machine, that you can just ask if you are allowed to make a transition and return a set of properties to update or a function to execute call setState({...})
based on that information.
4:
Reflux looks great, as it seems to reduce the boilerplate quite a bit. Reflux may or may not perform as well as stock Flux
however.
Let me know how it goes, as your strategy may help me improve my structure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With