Giter VIP home page Giter VIP logo

Comments (23)

ryanbrainard avatar ryanbrainard commented on May 21, 2024

Have you tried using andThen as @hnordt suggested in #47?

from react-refetch.

eyalw avatar eyalw commented on May 21, 2024

@ryanbrainard, can you explain how it helps in the scenario I described?
I see @hnordt has a prop array named 'history' given to the wrapped component,
and promise value is pushed into that array.

I actually want to put the promise value into the wrapped component state (for example).
or - redirect (which will require access to this.context.router with react-router API).

from react-refetch.

arbesfeld avatar arbesfeld commented on May 21, 2024

FWIW, I also have had to do this, and have been using a pattern like this:

componentWillReceiveProps(nextProps) {
  const { createProjectResponse } = nextProps;
  if (createProjectResponse && createProjectResponse.fulfilled) {
    this.onDismiss();
  }
}

But it would be nice if the createProject just returned a promise.

from react-refetch.

eyalw avatar eyalw commented on May 21, 2024

@arbesfeld this works because onDismiss() will close the view component you are in.
but if it didnt, (e.g. setState, or update view) - on the next "willReceiveProps" the onDismiss() will be called again and again... so it doesn't make sense for me.

Really surprised such a classic scenario does not have an answer in RR. I really like the design pattern of RR, its really simple and declarative, no boilerplate code. I wish the HOC will call a callback I defined,
or at least have the createProject() return a promise.. (less prefered)

from react-refetch.

eyalw avatar eyalw commented on May 21, 2024

@ryanbrainard any idea?

from react-refetch.

eyalw avatar eyalw commented on May 21, 2024

What I ended up doing was wrapping my component with my own HOC below the Connect HOC, which middlewares the willReceiveProps lifecycle method and checks for a change in promiseState.settled value between this.props and nextProps, and triggers an exposed function on the wrapped element.

I wish it was a built in function though

from react-refetch.

ryanbrainard avatar ryanbrainard commented on May 21, 2024

@eyalw Sorry for the delay getting back to you. I would like to support your use case, but I'd like to understand it a little better:

Is there a reason you want to pass in the callback as a ref? Does that give any advantage over proving a function that takes the wrapped component as an argument? I don't use refs very much, so perhaps I'm missing something.

@ryanbrainard, can you explain how it helps in the scenario I described? I see @hnordt has a prop array named 'history' given to the wrapped component, and promise value is pushed into that array.

I don't think that history is an array, but rather the history from https://github.com/reactjs/history being injected as a prop by react-router. The push should be doing redirect, not adding to an array.

What if meta contained a reference to the wrapped component with, so you could do something like this?

connect({
  fetchAccountPs: {
     method: "GET",
     url: "/some/url",
     andThen: (_, meta) => {
        meta.wrappedComponent.onAccountFetched()
        return {};
      }
  }
)...

Not sure if this is the best place to expose this, but just spitballing a bit. I'd like to do this in a supported, clean way, but would like to understand the requirements a bit better to see if RR should be calling the function on your behalf, if the promise should be exposed in meta, or what is the best approach. If anyone want to open a PR with idea, that would be welcomed as well. I personally don't have any need for this, so a PR will probably be the faster than waiting for me to do something :)

from react-refetch.

eyalw avatar eyalw commented on May 21, 2024

@ryanbrainard I like your idea. Your API seems more flexible, and you can control the function being called better, and add conditions and pass different values.

I do also like it when an API offers me to code the common case in shorter way, which I think is: wrappedComponenet[calbbackName](err, returnVal) - so I guess I would have preffered to have a shorthand as well

As to your question about my use case, its mostly stuff like:

onFetchAccountResponse(err, account) {
  if (!err)
    this.setState({ account }); // load data into a state-binded-form-fields
}
onSaveAccountResponse(err) {
  if (!err) {
    showNotification('success', 'Wohoo! Account saved'); // one time GUI notification
    this.context.router.redirect('/somwhere'); // redirect
  }
}

onChangePasswordResponse(err) {
  if (!err) {
    showNotification('success', 'Your password was changed'); // notify again, and:
    this.setState({ formData: null }); // clear the form fields
  }
}

from react-refetch.

neezer avatar neezer commented on May 21, 2024

I'll chime in in support an implementation for this behavior, as #66 (duplicate of this issue, effectively) illustrates my use case.

Also, @hnordt's solution doesn't work for me since I'm using react-router v2, where router is defined on this.context (this.props.history is being deprecated).

You can still workaround that fact using the singleton history, but you're going to run into issues with universal apps with differing history strategies (in-memory vs browser).

from react-refetch.

eyalw avatar eyalw commented on May 21, 2024

@ryanbrainard I'm interested to learn, when andThen() will be called, and will make a call to a function on my component, what is the props of the component at that instant? are they already updated with the new fetched data? was willReceiveProps already called for the wrapped component or not?

from react-refetch.

ryanbrainard avatar ryanbrainard commented on May 21, 2024

@eyalw andThen is called in the callback to setState. This is inside of the promise fulfillment handler, so it will be called after the fetch successfully returns and the JSON is parsed.

what is the props of the component at that instant?

The prop should be fulfilled

are they already updated with the new fetched data?

yes

was willReceiveProps already called for the wrapped component or not?

yes


I think what you are getting at here is that it might not work since it's already updated. then by contrast is called before setState and could be used with an identity request, but feels like a crappy workaround:

connect({
  fetchAccountPs: {
     method: "GET",
     url: "/some/url",
     then: (value, meta) => {
        meta.wrappedComponent.onAccountFetched()
        return {value, meta};
      }
  }
)...

So, if we create a new place to do this kind of thing, where would be the best place in here so that to happen? ...or, would then or andThen actually work? It would be nice to leverage them if possible so we don't have a sprinkling of hooks everywhere, so something that uses them as is or extends them would be prefered, but not totally against adding something new if its needed.

from react-refetch.

eyalw avatar eyalw commented on May 21, 2024

having both then and andThen as 2 different times to hook into - before and after the props have passed down to the wrapped component - seems great to me.
I was asking because I was thinking my wrapped component callback might be using "this.props" to get the new value, or must it be passed in the callback.

from react-refetch.

yarinm avatar yarinm commented on May 21, 2024

I would really be happy to see @ryanbrainard suggestion implemented.
But why do we need to return {value, meta}? can't we also support an empty return ?

from react-refetch.

amoskl avatar amoskl commented on May 21, 2024

+1

from react-refetch.

uripo avatar uripo commented on May 21, 2024

+1

from react-refetch.

XAMeLi avatar XAMeLi commented on May 21, 2024

+1

from react-refetch.

gaugau avatar gaugau commented on May 21, 2024

I encountered the same scenario as @eyalw. Where I just want to trigger an action eg. updateUser and then performing an action (eg. show notification). I think it's common case and the documentation should be updated to show an example of how to achieve it with RR.
Currently, I need to hook into componentWillReceiveProps to check if the response has been fulfilled and perform the callback action. But any changes on props later could trigger the same callback action multiple time. :(

from react-refetch.

eyalw avatar eyalw commented on May 21, 2024

@ryanbrainard any updates on this issue? I think meta.wrappedComponent is a very good addition to the API.

from react-refetch.

ryanbrainard avatar ryanbrainard commented on May 21, 2024

@eyalw Thanks for bringing this up again and opening the PR.

@yarinm, the change in #128 should allow for an empty return.

from react-refetch.

Soul-Burn avatar Soul-Burn commented on May 21, 2024

In my case, I want to show a dialog window when the result was fulfilled.
In e.g. material-ui this is done by sending a open="true" prop to the dialog, usually coming from the state/props of the parent. It is then closed when a button is clicked and the handler sets the state of the parent.

While the fetch promise prop doesn't exist, the dialog is not shown.
When it exists and pending, I show a loading animation.
When it fulfilled, I show the dialog.
However, there is now no way to now dismiss this dialog, as the promise will remain until it is replaced/refetched.

A one time callback like proposed here will let me set the dialog state.
I can work around this by defining a "value" fetcher and relying on this value rather than the promise's fetching state.
However, in my case, and along the lines of RR taking care of state, it makes more sense to have a way to dismiss the existing PromiseState and return it to how it was before the fetch function was called to designate the of this flow.

Something like this could work (not tested):

connect(props => ({
  shouldShowDialog: { value: false },
  dismissDialog: () => { value: false},
  postStuff: data => ({
    stuffRequest: {
      method: 'POST',
      url: '/stuff',
      andThen: () => ({
        shouldShowDialog: { value: true }
      })
  })
}))(MyApp)

Then my code could use the value in shouldShowDialog combined with the stuffRequest promise state.

That said, is there anything limiting us from passing this into the function and simply call stuff on it in the andThen?

connect(props => ({
  postStuff: data, component => ({
    stuffRequest: {
      method: 'POST',
      url: '/stuff',
      andThen: () => ({
        component.doStuff();
        return {};
      })
  })
}))(MyApp)

from react-refetch.

ryanbrainard avatar ryanbrainard commented on May 21, 2024

is there anything limiting us from passing this into the function and simply call stuff on it in the andThen?

I don't believe there is (didn't try it), but @eyalw 's proposal in #139 has the nice property of also working in cases where you aren't calling a fetch function.

from react-refetch.

Soul-Burn avatar Soul-Burn commented on May 21, 2024

Makes sense.

What about the proposal of dismissing a fetch, back to how it was before it was fetched?

So we could have rendering like this example:
no fetch - nothing shown
pending - loading animation
fulfilled - some result, possibly a dialog showing
rejected - another result, possibly a dialog showing
Once the dialog is done, the fetch can be dismissed to move it back to the original state.

from react-refetch.

eyalw avatar eyalw commented on May 21, 2024

Can we close this issue now?

from react-refetch.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.