Open markerikson opened 3 years ago
Just FYI, I should have a JS version of the RN template as well as TS and JS versions for Expo coming soon. Will look into adding these to the docs in a way that doesn't look ridiculous.
I've worked a bit on the RN docs side of things. I think a PR is ready for that one. I wanted to wait until I added the NextJS section but had some questions on it first.
You mentioned that we probably want to document usage of NextJS's data fetching APIs, but the template linked doesn't seem to use getStaticProps
or getServerSideProps
. Is this still something we want to look into documenting?
AFAIK, even prior NextJS projects I've worked in before have tended not to utilize these methods in prod
Yeah, that's something that had crossed my mind.
Part of me says that not everyone is going to need to do SSR-type behavior and need next-reducer-wrapper
. I've actually got a Next app at work right now, and we're not using that at all.
But, it's also a common enough thing that I can see the point in having the official Redux+Next starter project have that built in to at least show how it should be set up.\
I know that the Next folks are happy to accept PRs to improve those projects, I just don't have time to even think about that work myself.
You know, I honestly just didn't even know about next-reducer-wrapper
until you pointed it out. After looking into it more, it definitely seems like the ecosystem's choice for doing the SSR-hydration with Redux
It even has a NextJS repo example: https://github.com/vercel/next.js/tree/canary/examples/with-redux-wrapper
If we're okay with using the next-reducer-wrapper
as the jumping off point for NextJS I think I can draft different smaller sections ("this is how to do it without SSR, this is how to do it with, here's the difference") as part of the parent. I'll see what I can do this weekend
Sounds good!
It may be worth at least mentioning that RTK 1.7 will have SSR support as well.
I wrote a Reddit comment recently about how Next and Redux fit together:
Pasting here for ease of reading:
Depends on how you're trying to use Redux, in much the same way that it depends on how you're trying to use React.
If you're only using Next as a client-side tool (ie, like CRA but with multiple pages), then conceptually your Redux usage is similar. Create a store on the client side, dispatch some actions, fetch some data, etc. Where it gets trickier is that A) Next has multiple pages instead of one, and B) even in the CSR-only scenario Next will try to statically generate HTML for each page by default. That means you have to set up the Redux scaffolding so it creates a unique Redux store on demand per page, rather than just once from
index.js
like you would in a CRA app. I showed an example of the store creation setup code I cobbled together for this use case based on some Next examples.Another question is whether you're going to have one store for the entire app regardless of what page you're on, or whether you're going to have different stores with different reducers for each page. I started out with separate stores per-page, and then later switched to one store for the entire app containing all reducers regardless of page.
The SSR question is separate. Redux has always been usable for SSR scenarios - even the original README says "works great in isomorphic apps because it doesn't use singletons and the data can be rehydrated". The basic pattern is:
- Create a Redux store on the server during the request. Fetch some data, do initial React rendering to HTML string.
- Get the Redux store state and include it in the generated HTML as a global JS variable
- On the client side, create the store and pass in that serialized state to act as the initial state
The same pattern applies here to Next usage, except that it is again more complicated due to the multi-page setup scenario and Next's different options for fetching data on the server.
That's why there's a fairly complex library called https://github.com/kirill-konshin/next-redux-wrapper , which tries to abstract the process of grabbing data from the server-side APIs and rehydrating that data into the Redux store on the client side.
We actually just added SSR/rehydration support to RTK Query in the recent RTK 1.7 release, and we specifically have instructions and an example of using RTKQ in combination with
next-redux-wrapper
:
I just wrote up a fairly similar comment and am pasting here for posterity and later documenting:
With CRA, creating the store and adding the
<Provider>
is easy. There's already an easily visibleroot.render(<App />)
insrc/index.js
, and you just import the store and wrap that in<Provider store={store}>
.With Next, there is no one single
render()
call, because A) Next does that internally, and B) there are many pages.So what you typically have to do is add a
pages/_app.js
file and wrap that content in<Provider>
.It gets more complicated when you start considering the server-vs-client rendering behavior. Next automatically tries to pre-build pages on the server by default, along with rendering them on the client. That means your code has to handle running on the server, and that includes creating a Redux store for each page.
So, you end up having to write some extra code to manage creating an instance of the store on demand, and having that get used once on the server and again on the client.
THEN, what if you want to use something like
getServerSideProps
to do some data fetching and feed that into the Redux store on the server for the initial render? You would then want to pass that into the Redux store on the client side to initialize it with the same values used in the server render, but that takes extra work. The standard tool for helping with that is https://github.com/kirill-konshin/next-redux-wrapper , which abstracts the server data lifecycles, helping init the Redux store, and passing along the data from server to client.
Hiya! I can take care to add a good RN example but with Expo.
Expo is recommended for beginners/mid-levels based on RN docs and it has a lot of advantages.
π This could be motivating to new redux learners + existing developers (like me π) .
Also, I know experts in the React Native community who hadn't used Expo before, but today they changed their minds after hearing about Expo team's updates over the past 2 years, especially since the appearance of EAS services
Note: for more information about new Expo's features in recent years visit this link.
π I don't know about Next.js and will not be able to do anything on it.
Would you agree with me on working only on adding RN (example + docs) to redux website? π
Just give me the go π
thanks
@fregayeg honestly though, as redux is a non-native library there shouldn't be any discernible difference between setting it up with vanilla RN or expo, right?
@fregayeg honestly though, as redux is a non-native library there shouldn't be any discernible difference between setting it up with vanilla RN or expo, right?
I think yes! We can consider redux in both RN & Expo as third-party acceptable dependency. Maybe the only difference is: When using Expo Go app, debugging with redux devtools could not work properly. But DW I have experienced such case and today I know how to solve this in few simple ways π( it'll be obvious to add these information). So do you agree ?
@fregayeg : FWIW, the request in this page isn't actually for a full-blown app :)
What I'm looking for is something sort of along the lines of the existing "Configuring Your Store" page, that would answer questions like:
ReactDOM.render()
- where do I add the <Provider>
to the component tree? @fregayeg : FWIW, the request in this page isn't actually for a full-blown app :)
What I'm looking for is something sort of along the lines of the existing "Configuring Your Store" page, that would answer questions like:
- Where does the store live in the folder structure?
- There's no
ReactDOM.render()
- where do I add the<Provider>
to the component tree?- Any other unique aspects of adding Redux to an RN project that would be different from the typical basic CRA/Vite SPA process
Ok but there is some other interesting topics such:
Testing with react-native-testing-library.
π Some components are only in mobile, and may need a useful state management system such Redux. One of these component is called bottom-sheet. π That's why I'd like to give few examples on these topics as they seem to be interesting and required for RN developers.
Hmm. @fregayeg , I definitely want any differences in Redux DevTools setup covered (if there are any), but I don't think we need to worry about navigation or testing.
My 2 cents regarding Next.js. First my current understanding is that Redux is already SSR friendly, which explains why the Next.js official redux example is pretty straightforward.
In previous versions, you could use getServerSideProps
or getStaticProps
at page-level to initialize your store with server data and pass it down to the client. You don't strictly need that, but it helps persisting some state, for instance keeping user preferences in memory.
In Next.js 13, each React Server Components is able to call some server code, and you can now do things at page-level. This means you have to handle a tree structure instead of top-level pages. Therefore, you might need a way to instanciate the store once and carry it around. But you don't have usual React context in RSC.
The alternative? The cache
function. This kind of usage is not yet documented but I've seen it in the wild and I am preparing a paper on the subject of "server context", soon to be released.
At the time of writing, Next.js 13 beta docs shows how to use cache for data fetching, but you can use it to return a Redux store instead: it will be initialized only once per request.
You can access request specific values via cookies
and headers
eg to find the current user.
(disclaimer: I don't use Redux and haven't in a while so take all this with a pinch of salt)
@eric-burel The Nextjs official redux example that you link there unfortunately does not work for SSR. If you want to use Redux with SSR on Next, you need additional logic that rehydrates the SSR state on the client, and makes sure that each SSR run has a separate Redux store. WIth that official example, all SSR pages would share one store between all users.
=> Redux + NextJs requires the use of https://github.com/kirill-konshin/next-redux-wrapper
We will probably wait what https://github.com/kirill-konshin/next-redux-wrapper brings to the table for Next 13, since it is already impossible to use Redux + Next SSR without that.
Some related next-redux-wrapper
notes in this issue:
WE'VE FINALLY GOT DOCS FOR SETUP WITH NEXT!!!!
Our docs currently teach app setup based on a standard SPA-style approach, and specifically with use of Create-React-App. Related, our installation instructions currently point to the two RTK templates for CRA (JS and TS).
We should add additional installation and setup instructions for other major React environments, like React Native and Next which both differ significantly in how the app structure is defined and have different considerations (no
ReactDOM.render()
call in RN or Next, and Next users will likely want to integrate with Next's data fetching APIs).We could possibly do this by updating/rewriting https://redux.js.org/usage/configuring-your-store to be more about "how do you set up a Redux store in various environments?" and covering RN/Next specifically as part of that, or we could keep the idea of "store configuration" and "app project setup" in separate pages.
Related to this, it would be nice if we could point to specific templates for those environments as well.
For RN, there's https://github.com/rahsheen/react-native-template-redux-typescript , which ports the RTK+TS example to the RN CLI.
For Next, there's https://github.com/vercel/next.js/tree/canary/examples/with-redux , which does something similar.