Limenius / ReactBundle

Client and Server-side React.js rendering in a Symfony Bundle
MIT License
390 stars 53 forks source link

SSR issues (should implement react_component_hash ) #28

Closed grimpows closed 6 years ago

grimpows commented 6 years ago

i'm using your bundle since a while now, and i'm front of a problem that may will make me re-do my project without reactBundle that mean symfony for only API, node server for fetch api and render html (SSR).

Why ? simply cause there is actually no easy way to do a proper SEO for App using ReactBundle. Actually for using ReactRouter with a route Array who get, for exemple, data like Title, meta description etc ...

with a solution like react_component_hash from react_on_rail, i would not have to pre-calculate from php wich route i should use for SEO as i would simply use the title/meta returned from javascript(serverside) with phpv8 or dummy node server. this solution would be more simplier and prevent error, as i'm not using the exact same function than react router for calculating wich route will be render from react router, that can lead to some miss-calculated route. actually i have implemented almost function for php side from there to my router manager https://github.com/gpolguere/path-to-regexp-php

you can see its a bit problematic, and i guess you should encounter the same problem with your own APP

so, the question is, does there is a simple way to just adding this react_component_hash ? here is the exemple from react_on_rail https://github.com/shakacode/react_on_rails#generator-functions

for tip, i tryed before to do php pre-calculate route match, to use a little app, who use my redux store, where is stored the data from the actual route matched (javascript side) and render this little app like this in my tiwg template :

{{ redux_store('MySharedReduxStore', initialState ) }} // this store also pre-calculated the route matching via props send to it
<head>
   {{ react_component(titleApp) }} // this return a <title>{title_from_redux_data}</title>
  // could do the same for meta
<head>
<body>
   {{ react_component(mainApp) }} // return content
</body>

but this not really working as this render the routeTitle in the body and put a react_on_rail script where i would have direct html render of component and this is not the proper way to render this SEO component, same for meta or any lang tag in html

another downside too on using phpJs intead of a regular NodeJs server is that we cant Prefetch fromServerSide rendering. For resolve this prob, we have to send our data by initialProps of reduxStore, but that work only if the data required is accesible through our repository, this isnt working for fill our APP with api from other websites. Also, to know wich data should be send we have to know wich route will be render too, that lead to the same problem i encounter for SEO

thanks a lot for your work, this helped me a lot for learning react, and building a pretty cool symfony/react Project, as i'm not familiar at all with phpJs i guess i'll not helpfull for trying implement this great fonctionnality

nacmartin commented 6 years ago

Yeah, it sounds like a good addition. I am implementing React_component_hash... maybe calling it with another name but same thing.

grimpows commented 6 years ago

đź‘Ť
for use case exemple, seem i have frogot add this link : https://github.com/shakacode/react_on_rails/blob/master/docs/additional-reading/react-helmet.md

if that can help ^^

thx :)

nacmartin commented 6 years ago

Sure, it has been implemented and there is an example in the sandbox now.

nacmartin commented 6 years ago

By the way, ReactHelmet is much better to deal with this situation than changing the title with jQuery.

grimpows commented 6 years ago

wooo, fast implement ! dunno how you do as fast, but gratz, i just looked sandbox for see how you use the new twig function !

another question but may i'll do another issue from liform-react. I'm using your schema for form, for exemple, i'm returning the schema when fetch "post" on /:local/api/user with a empty content. This working well, exept that work only after the SSR, because fetching isnt applied on SSR, i tryed but lead me to an error, so i moved the fetch on didMount(), and if i would be able to use fetch on SSR, this will still not work cause SSR dont wait about this async func.

what that do in fact ? i'm showing a loading circle as SSR in place of the real login form because i dont get the schema data yet. i could, send this schema data from symfony controller but this isnt the proper solution to do as i dont want emulate the "matching route in react" anymore, so i'll not know when to send this schema and i think isnt a good practice so send every schema possible of the APP as initialProps, that will lead to perf issue with big app and its against how react should work(i guess).

so any idea on how i could pre-fetch on SSR a schema(or anything else ^^) from API depending on route ? :p ps : i'm not using a nodeJs dummy server, but if i have to i'll(for dev i mean). as that seem phpJs can't use fetching func ^^

i saw some exemple with node, like using the res.send() function inside a fetching, but no idea how we could use as react_on_rail dont expect about a res.send() i guess