jsdf / react-native-refreshable-listview

Deprecated. A pull-to-refresh ListView which shows a loading spinner while your data reloads
1.38k stars 168 forks source link

Why uses promise? #18

Open lazywei opened 9 years ago

lazywei commented 9 years ago

Hi,

I'm just wondering why we need to use promise when invoke loadData? I thought in React, the better way to do this is via Flux + Store + State. For example, we have a "loading" state, and let the RefreshableListview decides whether to show spinnger according to that state. In that way, things become more easy to handle. Otherwise, the promising will introduce extra "async" behavior to the view, which in my humble opinion is not the best way.

How do you think? Thanks

jsdf commented 9 years ago

The Promise/callback is to handle the sequencing of UI changes (minimum display time, minimum time between refreshes etc). If you want manual control over the states you can use the underlying ControlledRefreshableListView, which is stateless and just makes use of isRefreshing and onRefresh props, however IMO this is less of a good developer experience as then you have to manage the timing/sequence yourself.

jsdf commented 9 years ago

Actually I see what you're saying with regard to Flux, perhaps I'll change it to observe an isRefreshing prop changing and hide the sequencing internally.

lazywei commented 9 years ago

Actually I see what you're saying with regard to Flux, perhaps I'll change it to observe an isRefreshing prop changing and hide the sequencing internally.

Yeah, this is what I was trying to say. I think if we listen to an isRefreshing props, then we might also need to take a prop that is a callback, e.g. handleRefreshingTrigger, so that I can update the props in that callback. For exmaple

getInitState() {
    return { isRegreshing: false}
},

handleRefreshingTriggering() {
    this.state.isRefreshing = true;
    this.Flux.Actions.loadNewData().then(() -> {
        // better yet, let Store control this state
        this.state.isRefreshing = false
    }); 
},

render() {
    return (<RegreshableListView
      isRefreshing={this.state.isRefreshing}
      handleRefreshingTriggering={ this.handleRegreshingTriggering } />
}

How do you think?

eyaleizenberg commented 9 years ago

@lazywei I am also using flux in my app and I did something like this:

reloadIncidents: ->
    new Promise((resolve, reject) =>
      resetListAndResolve = =>
        IncidentsStore.removeIncidentsResetListener(resetListAndResolve)
        @updateList()
        resolve()

      IncidentsStore.addIncidentsResetListener(resetListAndResolve)
      @resetIncidents()
    )

This way I still return a promise but I am still using the usual action -> dispatcher -> store -> view flow

imothee commented 9 years ago

+1 to not requiring a promise/callback for the loading of data.

Perhaps it can do both and if a prop isLoading={this.state.whatever} is set it can watch that else it can watch the promise?

Was there any progress on this, happy to look at a pull request to do the above.

gre commented 8 years ago

-1. I really think Promise should be more considered in component like these :)

It's just a way to tell the lib what is the state of the data you load without introducing more complex handling on the user side (with a state, and also it can be complex to handle when you start having concurrent calls..).

Promise is not at all incompatible with Flux approach. I'm using both. if using Redux, the returned value of dispatch(...) is the returned value of the action, so just make sure the promise of the fetch() get returned all along and you are done.

I also found promise perfect to use on UI elements like buttons: you can make a button that accept a onPress callback, and if the onPress returns a promise, the button will be in pending state (a bit transparent and not touchable during the pending).

mauron85 commented 8 years ago

+1 to not requiring a promise/callback for the loading of data.