Asaf Katz
Asaf Katz

Reputation: 4688

Handling UI state with Flux and React

with MVC (and Angular in particular), when I want change the ui state in response to data change, I can use a Callback or a Promise to handle it in the controller level, like so:

API.voteUp(ITEM_ID).then(function () {
  $scope.isOpen = false;
});

with Flux, instead we fire an Action, like:

ItemActions.voteUp(ITEM_ID)

but there is no way to react directly to the action

I do understand the reason behind it, an know that most state should live in the stores, and that a store should listen to VOTE_UP action and change the UI state accordingly. but it feels that it's not going to scale very well if I need to open a Store for every little UI. I feels that Flux and the View will become coupled very fast.

below are two scenarios to demonstrate the problem. the goal is to close the Item component in response to action and do not mess with the state of the other componenets

the code of the demo available here: https://github.com/asfktz/flux-ui-state-test

(I'm using Alt Flux, but the implementation doesn't really matter)

Scenario A: handling UI state in response to Action

1. open Item A and Item B

A1

2. Vote for Item A

A2

3. 'VOTE_UP' Action is fired.

Item A should close in respond to the Action - not before

(for example, if the action failed it should stay open) A3

Scenario B: Two different, non related components that handles the same action should not interfere with each other.

1. open Item A in both lists

B1

2. vote for Item A in list B.

B2

3. Item A of list B fire 'VOTE_UP' Action

votes update on both lists.

only Item A of list B should close B3

Notes:

This blog post describe the same problem

Upvotes: 2

Views: 576

Answers (1)

chriz
chriz

Reputation: 1896

the goal is to close the Item component in response to action and do not mess with the state of the other componenets

Think of stores as bag of states. If List A and List B are supposed to have a totally independent data, I would do this:

render () {
    return (
        <div className="main">
            <div className="votes-block">
                <h2>Votes List A</h2>
                <List items={this.state.itemsA}/>
            </div>
            <div className="votes-block">
                <h2>Votes List B</h2>
                <List items={this.state.itemsB}/>
            </div>
        </div>
    )
}

Basically having to maintain two items itemsA and itemsB for your two items.

Upvotes: 1

Related Questions