Open oyeanuj opened 6 years ago
If it helps, I'm using withJob up to 3 levels deep without problem. I'm also using JWTs for auth, but doing things a bit differently than you not that it should have much bearing on your question (ex: I have public/private routes so I wrap my auth HOC around just the private routes... I also don't call the server from the Auth itself aside from checking for the token, and instead make all further secure requests get verified on the server. If any of them fail, the user won't see anything and will be immediately redirected to login).
@unleashit Thanks for sharing that. I am curious what your setup looks wrt the nesting. I ask since my observation is that only if children are available in the initial parse that their jobs are being respected. I wrote more on my observation this issue in react-jobs. Maybe you could also chime in on that?
Hey @oyeanuj, I haven't had a chance to look into this deeply but I don't see why more than a first parse is necessary. I "would think" react-jobs + react-tree-walker would be able gather up all the promises before setting up a big "Promise.All" for everything found? I'm honestly not sure how it works under the hood though.
Unfortunately, I'd like to but I can't share the actual code with you because its under NDA for a client. But here's a stripped down example showing withJob in a parent/child combo which is working fine for me:
// I'm using withJob for the main App component, which holds the main Switch (meaning everything is a child of this)
export default withRouter(
compose(
connect(mapStateToProps, {
logout,
getData: getProductData,
}),
withJob({
work: ({ productData, getData }) => {
if (Object.keys(productData).length) {
// product data cache hit;
return productData;
}
return getData();
},
shouldWorkAgain: (prevProps, nextProps, jobStatus) =>
Object.keys(prevProps.productData).length === 0,
LoadingComponent: () => (
<Spinner />
),
}),
)(App),
);
An example of a child route:
export default withRouter(
compose(
connect(mapStateToProps, {
getOrders: getAllOrders,
getOrdersCount: getAllOrdersCount,
}),
withJob({
work: ({ getOrders, getOrdersCount }) =>
getOrders()).then(() =>
getOrdersCount(),
),
LoadingComponent: () => <Spinner />,
}),
)(Admin),
);
I also have another withJob nested for each page of within the admin. It might help to say I'm not directly using the data returned from react-jobs in my render functions but instead using mapStateToProps to get it from the Redux store (I have actions/reducers doing that work).
So it's working and to me seems pretty straightforward. It just works(tm). If you're trying to do something different then this then I'm sorry I butt in.
@unleashit Thanks for sharing that! So it seems like what was really causing the issue was having nested react-jobs on components that are dynamically imported (which don't seem to resolve on server-side). Here is the ticket for that - https://github.com/ctrlplusb/react-tree-walker/issues/27
I'm also dynamically importing, but for whatever reason you might have to add a promise to get them to work together. See: https://github.com/ctrlplusb/react-jobs/issues/51
So, one of the problems while using this kit that I haven't been able to solve is being able to fetch data on server-side for more than one component in the tree. A typical case is with the following hierarchy:
In this setup, the
JWTHandler
has to fetch some data (to validate the JWT token) usingwithJob
, and theProfilePage
has to fetch profile data usingwithJob
as well before the page is handed to the client.But when I implement it like that, only the
withJob
fromJWTHandler
is run on the server and the one fromProfilePage
is run on the client.So, I am curious if this is possible using react-jobs, if folks have come across such a case in their usage, and what strategies have worked out for people?
cc: @ctrlplusb @birkir @strues or anyone else who has experience with this