-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
work() should get the exact props passed to the component #9
Comments
Woah, interesting case! Do you have an example of how you may use this? |
I've added you as a collaborator! We will have to update the package.json with your details. I appreciate your interest and help here! |
thanks! My main gripe is that <Match pattern='/foo' component={Foo} />
@withJob(props =>
fetchPage(props.id)
)
class Foo extends PureComponent {} The above pattern only needs to load data once in its lifetime. If the route changes the components gets unmounted and when the route goes back to As such, I actually want my default interaction to behave exactly like the simple caching example: https://github.com/ctrlplusb/react-jobs#simple-caching-of-asynchronous-job I'm a big proponent of building abstractions that give you as few ways of shooting yourself in the foot as possible, so instead of relying on a convention to always do the above, I want to abstract the functionality in a wrapper method: import {withJob} from 'react-jobs/ssr';
// Only fetch if there is no job in progress and the job isn't done
const defaultFetch = ({job}) => !!(!job || (!job.completed && !job.inProgress));
const DataLoader = ({fetch, shouldFetch=defaultFetch}) => Component => {
let cache = null;
return withJob(props => {
if (!shouldFetch(props)) return cache;
return fetch(props).then(result => {
cache = result;
return result;
});
})(Component);
}; The above abstraction does not care what you do with your data, if you store it in a redux store or somewhere else, or what its prop name is (which is a caveat of the caching example). It does not allow you, by default, to refetch and it also prevents you from importing now, the above becomes: import DataLoader from 'data-loader';
@DataLoader({
fetch: ({route: {params: {id}}}) => fetchPage(id), // <-- Will only ever get called once
})
class Foo extends PureComponent {} ... come to think of it, do you have an use-case for data-refetching that's more common than a one-time use per lifecycle? |
That is great and I am so glad that you are seeing the potential for abstraction as this was a big part for me in creating the functional API. 😀 In regards to executing the work on mount and possibly again on receiving props. This is actually a bug come to think of it. We need to amend the |
but the question is, do you want to allow for re-fetching of data at all? I've used things like redux-async-connect before which does not give you the option of re-fetching and I've never actually noticed it missing as I haven't come across an use-case for it |
I think if you aren't connecting to a state management system then there is sufficient need for the job to fire again. Its easy enough to write your own wrapper to prevent this case of course, but then it can be a choice. I want it to be a flexible abstraction. |
@smirea I have done a To be honest I am a bit opposed to it at the moment. It feels a bit confusing to myself, but I am open for discussion. 😀 |
awesome! I think now this becomes a bit too inflexible since you're effectively enforcing that [1] technically |
A very interesting point! I shall think on this one for a while. Thanks!
Then when any prop updates come from a parent the work could be fired again unless we check for these conditions.
If the component is unmounted then mounted again then it would fire again. For very simple apps this makes sense. E.g. a component per "page" that fetches it's data every time you browse to the page. -- The failure/retry case is very interesting though! I think we should consider adding an option to the Thanks so much for all your sense checking! I really appreciate it. 🙏 |
sounds good.
it's still nice to have it just so you have the exact same props in both cases. not sure what other tactics can be performed down the line if this API is exposed, but I don't necessarily see any reason against exposing it, since it's passed down to the child component anyway. relevant side-note: at the very least remove the 2 internal props that are passed :) |
Done in release |
they were removed from being passed to the child, but they are still passed to |
Aha! Thanks again. You have been awesome at spotting these issues for me! |
right now
work()
has access to the 2 internal methods ofwithJob
and does not have access to thejob
state itself.It's probably debatable whether the
work()
method should have access to thejob
state, but I guess it could be useful for the cases where you want to perform logic depending on where the job is inProgres or not (e.g. cancel in-flight jobs if you're using a .then-able observer or something)The text was updated successfully, but these errors were encountered: